我正在从后台队列创建并向Core Data添加大量托管对象。我的理解是我无法从后台线程访问上下文,所以我使用performBlock来安排将Core Data添加回创建上下文的同一队列。这很好用......
我的问题是在测试期间我注意到,通过删除[moc performBlock:^{ ... }];
,应用程序仍然按预期执行(甚至可能更快一秒)我是否需要performBlock
?我会假设我这样做,并且它正在以非线程安全的方式工作(现在:),我只是想检查以确保我的理解没有缺陷。
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(backgroundQueue, ^{
// GET DATA
// PROCESS DATA
NSManagedObjectContext *context = [[self managedDocument] managedObjectContext];
[moc performBlock:^{
// ADD TO CORE DATA
[Core createRodInContext:context withDictionary:fuelRodDictionary];
}];
});
编辑:为createRodInContext添加了实现...
+ (Rod *)createRodInContext:(NSManagedObjectContext *)context withDictionary:(NSDictionary *)dictionary {
// CREATE
Rod *rod = [NSEntityDescription insertNewObjectForEntityForName:@"Rod" inManagedObjectContext:context];
// POPULATE
[neo setDataCode:[dictionary objectForKey:@"dataCode"]];
[neo setDataName:[dictionary objectForKey:@"dataName"]];
[neo setDataReference:[dictionary objectForKey:@"dataReference"]];
...
return rod;
}
答案 0 :(得分:5)
在后台线程中,必须使用 [moc performBlock:^{ ... }]
在主要托管对象上下文中插入(并填充)托管对象。
省略performBlock
意味着您也在另一个线程(与后台队列关联)中使用托管对象上下文(在主线程上创建)。
这可能偶然,但是一旦主线程在与后台线程相同的时刻访问MOC,结果就是不可预测的,因为(如你所说),MOC是不是线程安全的。
另见Concurrency Support for Managed Object Contexts 在OS X v10.7和iOS 5.0的核心数据发行说明中:
限制(NSConfinementConcurrencyType)。
这是默认值。您 承诺除了那个之外的任何线程都不会使用上下文 你创建它的。
但是对于其他并发类型(专用队列,主队列),除非您的代码已经在与MOC关联的队列上执行,否则您始终必须使用performBlock
(或performBlockAndWait
)。