我正在处理一个奇怪的案子。我从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
这样,所有对象都不是主线程上的错误。
答案 0 :(得分:1)
如果在后台线程上创建了这些对象(items
的内容),则无法在主线程中使用它们。您无法在线程之间传递NSManagedObject实例。
你必须传递NSManagedObjectIDs(在你保存后台MOC之前它不会是永久的),或者在主线程上使用NSFetchedResultsController(指向主MOC)。这是NSFetchedResultsController的设计案例之一,所以我建议你走这条路。