【发布时间】:2016-05-16 18:11:21
【问题描述】:
我最近开始尝试使用 Core Data 较新的 initWithConcurrencyType:NSPrivateQueueConcurrencyType 构建托管对象上下文。在使用这种类型的 MOC 时,我们应该使用performBlock: 或performBlockAndWait: 来“确保块操作在为上下文指定的队列上执行。”
作为其中的一部分,我将initWithEntity:insertIntoManagedObjectContext: 的托管对象创建调用在 performBlock: 块中,以便在 MOC 的私有队列上运行。
这符合Apple's Core Data Concurrency文章中显示的策略:
[private performBlock:^{
for (NSDictionary *jsonObject in jsonArray) {
NSManagedObject *mo = ... ; //Managed object that matches the incoming JSON structure
}
NSError *error = nil;
if (![private save:&error]) {
NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
abort();
}
}];
我已经 found myself 在 void 方法中初始化托管对象,这些方法实际上在完成块中返回新创建的对象。
+ (void)managedObjectFromJSON:(NSDictionary *)json completion:(void (^)(XYZManagedObject *object))completion;
与简单地从 JSON 解析方法返回对象相比,这种架构引入了复杂性。我似乎也遇到了与此设计相关的并发问题/崩溃,可能是在这些完成块构造函数中链接在一起的关系托管对象的异步加载中。
我的每个托管对象都执行以下操作,通过从 performBlock: 块中调用的完成块返回创建的对象。
[managedObjectContextPrivateQueue performBlock:^{
NSEntityDescription *entity = [NSEntityDescription entityForName:@"entity" inManagedObjectContext:managedObjectContextPrivateQueue];
XYZManagedObject *managedObject = [[XYZManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:managedObjectContextPrivateQueue];
[managedObjectContextPrivateQueue save:&error]
completion(managedObject);
}];
或者,是否可以在 performBlock: 块之外创建托管对象,并且只将插入/保存操作移到内部?注意NSEntityDescription方法确实需要访问块外的MOC。
NSEntityDescription *entity = [NSEntityDescription entityForName:@"entity" inManagedObjectContext:managedObjectContextPrivateQueue];
XYZManagedObject *managedObject = [[XYZManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];
[managedObjectContextPrivateQueue performBlock:^{
[managedObjectContextPrivateQueue insertObject:managedObject];
[managedObjectContextPrivateQueue save:&error]
}];
return managedObject;
或者,也许我应该使用performBlockAndWait: 等待块运行,然后直接从方法中返回托管对象,而不是从完成块中返回。
当托管对象上下文调用应该通过performBlock:私有队列进行路由时,托管对象应该如何创建和返回?
【问题讨论】:
-
为什么不能将 'managedObjectFromJSON:` 消息放入块中?
-
我为 NSManagedObject 找到的唯一初始化程序需要一个上下文 - 并将对象插入其上下文中。如果我理解正确,则此插入必须发生在 PerformBlock: 或 PerformBlockAndWait: 中,我希望我在这里错了,但是...
标签: ios objective-c multithreading core-data nsmanagedobject