在后台创建的NSManagedObjects在主线程

时间:2017-03-30 11:24:47

标签: ios objective-c multithreading core-data

我正在处理一个奇怪的案子。我从API获取一些数据,将响应JSON转换为NSManagedObjects并保存它们,所有这些都在后台线程中并使用其父级为NSPrivateQueueConcurrencyType的{​​{1}}上下文。

同时我正在创建NSManagedObjects,我将它们放在一个数组中,通过在主therad上执行的完成块在我的视图控制器中使用它。这是我正在做的简化版本。

NSMainQueueConcurrencyType

奇怪的事情发生在完成块内。我在该块的第一行放置一个断点并在控制台上打印- (void)getObjectFromAPIWithCompletion:((^)(NSArray *objects, NSError *error))completion { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ NSManagedObjectContext *backgroundMoc = [[CoreDataStack sharedManager] newChildContextWithConcurrencyType:NSPrivateQueueConcurrencyType]; NSArray *items = [self processToParseResponseFromAPIAndSaveInCoreDataUsingContext:backgroundContext]; [backgroundMoc save:nil]; dispatch_async(dispatch_get_main_queue(), ^{ //Beyond this point, all properties of items are nil or 0 (if integer) if(completion) completion(items, error); }); }); } 数组。一切看起来都很好,所有项目(在这种情况下为50)并且它们的属性都可以。

问题是当那行之后(我在items数组上没有改变任何内容)时,所有对象都变成了错误,我没有得到任何关于属性的数据。

不知道这种罕见行为的原因是什么。有什么想法吗?

感谢。

编辑:哈尔的回答让我走上正轨,所以这就是我为解决这个问题所采取的措施。在调用将在主线程上执行的块之前,我将托管对象从后台上下文“移动”到主上下文,使用它们的objectID进行获取。像这样:

items

这样,所有对象都不是主线程上的错误。

1 个答案:

答案 0 :(得分:1)

如果在后台线程上创建了这些对象(items的内容),则无法在主线程中使用它们。您无法在线程之间传递NSManagedObject实例。

你必须传递NSManagedObjectIDs(在你保存后台MOC之前它不会是永久的),或者在主线程上使用NSFetchedResultsController(指向主MOC)。这是NSFetchedResultsController的设计案例之一,所以我建议你走这条路。