【发布时间】:2014-12-10 04:58:29
【问题描述】:
最近,我一直在深入研究 Threaded CoreData,我阅读了这些教程:
- ZACoreData
- issue-10-core-data-network-application
就个人而言,我对 ZACoreData 方式感到满意。因为它坚持苹果规则。这会为每个线程创建一个上下文。
+ (NSManagedObjectContext *) contextForCurrentThread
{
if (!_managedObjectContextsDictionary) {
_managedObjectContextsDictionary = [[NSMutableDictionary alloc] init];
}
// Force the return of the main thread context.
if ([NSThread isMainThread]) {
return [NSManagedObjectContext contextForMainThread];
}
NSThread *currentThread = [NSThread currentThread];
if (![[currentThread name] length]) {
[currentThread setName: [NSManagedObjectContext generateGUID]];
NSManagedObjectContextConcurrencyType contextType = ([currentThread isMainThread]) ? NSMainQueueConcurrencyType : NSPrivateQueueConcurrencyType;
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType: contextType];
if ([currentThread isMainThread]) {
context.persistentStoreCoordinator = [NSPersistentStoreCoordinator sharedPersisntentStoreCoordinator];
}
if (![currentThread isMainThread]) {
context.parentContext = [NSManagedObjectContext contextForMainThread];
}
[_managedObjectContextsDictionary setObject:context forKey: [currentThread name]];
return context;
} else {
return [_managedObjectContextsDictionary objectForKey: [currentThread name]];
}
}
但是我的老板不想这样实现,他更喜欢使用 issue-10-core-data-network-application,这个演示甚至无法运行,因为他们的 web 服务无法运行。他们在主线程中同时初始化主线程上下文和背景线程上下文。之后,他们只需传递 backgroundContext 以在后台使用。
- (void)setupManagedObjectContexts
{
self.managedObjectContext = [self setupManagedObjectContextWithConcurrencyType:NSMainQueueConcurrencyType];
self.managedObjectContext.undoManager = [[NSUndoManager alloc] init];
self.backgroundManagedObjectContext = [self setupManagedObjectContextWithConcurrencyType:NSPrivateQueueConcurrencyType];
self.backgroundManagedObjectContext.undoManager = nil;
[[NSNotificationCenter defaultCenter]
addObserverForName:NSManagedObjectContextDidSaveNotification
object:nil
queue:nil
usingBlock:^(NSNotification* note) {
NSManagedObjectContext *moc = self.managedObjectContext;
if (note.object != moc) {
[moc performBlock:^(){
[moc mergeChangesFromContextDidSaveNotification:note];
}];
}
}];
}
他们是这样使用的:
- (void)import
{
self.batchCount = 0;
[self.webservice fetchAllPods:^(NSArray *pods)
{
[self.context performBlock:^
{
for(NSDictionary *podSpec in pods) {
NSString *identifier = [podSpec[@"name"] stringByAppendingString:podSpec[@"version"]];
Pod *pod = [Pod findOrCreatePodWithIdentifier:identifier inContext:self.context];
[pod loadFromDictionary:podSpec];
}
self.batchCount++;
if (self.batchCount % 10 == 0) {
NSError *error = nil;
[self.context save:&error];
if (error) {
NSLog(@"Error: %@", error.localizedDescription);
}
}
}];
}];
}
就我个人而言,我认为 issue-10-core-data-network-application 的实现方式是完全错误的,不符合苹果规则,即我们必须为每个后台线程创建一个 NSManageObjectContext。这样对吗?请给我你的意见。哪种方式实施正确?
【问题讨论】:
标签: ios multithreading core-data