【问题标题】:Core Data multithreading--what am I doing wrong核心数据多线程——我做错了什么
【发布时间】:2014-02-06 21:14:54
【问题描述】:

我会尽量保持简短,但基本上,我有一个应用程序,在某种模式下,它可以近乎连续地记录位置和其他数据,并拍摄照片(使用 AVFoundation)并将其全部存储在 Core Data 中。正如我所怀疑的那样,我发现所有这些都需要线程化……否则 UI 会变得非常缓慢。

我之前从未尝试过将 Core Data 与并发性结合起来,所以我尽可能地阅读它。我觉得我明白我应该做什么,但出于某种原因,这是不对的。我因此错误而崩溃:“非法尝试在不同上下文中的对象之间建立关系“managedDataPoint”。我知道这意味着什么,但我认为我下面的内容可以避免这种情况(我正在关注我读过的内容).. .因为我从主上下文中获得了一个对象 ID 引用,并使用它来获取对该对象的新引用并将其传递给“临时”上下文......但这不起作用,因为 Core Data 仍然声称我是尝试跨上下文创建关系(在哪里?)。感谢任何帮助。谢谢!

-(void)snapPhotoForPoint:(ManagedDataPoint*)point
{

if (!_imageCapturer)
{
    _imageCapturer = [[ImageCapturer alloc] init];
}

if (!_tempContext) {
    _tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    _tempContext.parentContext = self.managedObjectContext;
}

__block NSManagedObjectID* pointID = [point objectID];

[_tempContext performBlock:^{

    NSError *error = nil;

    Photo *newPhoto = [NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:_tempContext];
    UIImage *image = [_imageCapturer takePhoto];
    newPhoto.photoData = UIImageJPEGRepresentation(image, 0.5);

    ManagedDataPoint *tempPoint = (ManagedDataPoint*)[self.managedObjectContext objectWithID:pointID];
    newPhoto.managedDataPoint = tempPoint; // *** This is where I crash

    if (![_tempContext save:&error]) { // I never get here.
        DLog(@"*** ERROR saving temp context: %@", error.localizedDescription);
    }
}];
}

【问题讨论】:

标签: ios multithreading core-data grand-central-dispatch


【解决方案1】:

不应该

ManagedDataPoint *tempPoint = (ManagedDataPoint*)[self.managedObjectContext objectWithID:pointID];

不是

 ManagedDataPoint *tempPoint = (ManagedDataPoint*)[_tempContext objectWithID:pointID];

否则,您将使用不同的上下文!此外,您应该检查 objectID 是否是临时 ID,并在以下情况下获取“最终”ID。

【讨论】:

  • 但是我需要的对象是在主上下文中!它在方法的顶部传入。我想也许我只是没有正确理解这一点?如果我需要的对象已创建并存在于主上下文中,我如何从我的“临时”上下文中检索?我不认为它会在那里,除非我已经保存并从 main 推送到 temp ......并且我正在尝试另一种方式(从 temp 到 main)。
  • 您正在使用 objectID 并从 _tempContext 获取点对象,因此您可以在同一上下文中建立关系。与您描述的自己以及记录在案的完全一样。
  • 嗯...我试了一下,至少我不再崩溃了。不知道它本身是否“工作”,因为我没有测试过。非常感谢您提供的信息……不过,我仍然难以理解。如果我在一个上下文中为一个对象使用一个对象 ID,然后使用该 ID 查询另一个上下文,并且该对象在第二个上下文中不存在,它是否只是错误并为我创建一个,因为这两个上下文共享一个持久存储?
  • 在 10.7 之前,必须使用 NSManagedObjectContectDidSave 通知等来保持同步。然而使用 NSPrivateQueueConcurrencyType 就不再需要了。
  • 如果它正在工作,您可以将其标记为选中,以便其他人知道他们在这里找到了答案
猜你喜欢
  • 1970-01-01
  • 2015-12-12
  • 2014-10-01
  • 1970-01-01
  • 2013-03-02
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多