核心数据多线程——我做错了啥

Posted

技术标签:

【中文标题】核心数据多线程——我做错了啥【英文标题】: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);
    
];

【问题讨论】:

developer.apple.com/library/content/documentation/Cocoa/… 【参考方案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 就不再需要了。 如果它正在工作,您可以将其标记为选中,以便其他人知道他们在这里找到了答案

以上是关于核心数据多线程——我做错了啥的主要内容,如果未能解决你的问题,请参考以下文章

在 Perl 中近似 pi - 我做错了啥?

重新加载 ng-repeat 数据失败,我做错了啥?

Angular 6 - 从 observable 获取数据我做错了啥?

QTreeView 的 QAbstractItemModel:我做错了啥?

这个 MERGE / INSERT 查询我做错了啥?

这个 GraphQL 查询我做错了啥?