NSManagedObjectContext performBlock 内的 dispatch_async(dispatch_get_main_queue()
Posted
技术标签:
【中文标题】NSManagedObjectContext performBlock 内的 dispatch_async(dispatch_get_main_queue()【英文标题】:dispatch_async(dispatch_get_main_queue() inside NSManagedObjectContext performBlock 【发布时间】:2014-11-26 21:29:34 【问题描述】:我想做的是在后台线程上创建一个异步核心数据任务,以免破坏主线程,但我也想在工作完成后做主线程工作......
这是我的任务
-(void)doTaskwithCompletion:(coreDataCompletion)complete
[self.backgroundManagedObjectContext performBlock:^
// do my BG core data task
[self saveContext:self.backgroundManagedObjectContext];
complete(YES);
];
这是我的块方法
[[MYCoreDataManager sharedInstance]doTaskwithCompletion:^(BOOL complete)
if (complete == YES)
dispatch_async(dispatch_get_main_queue(), ^
// back to the main thread
);
];
有些东西告诉我这是错误的......但是一旦块完成后我找不到另一种方法让自己回到主线程......通知似乎太笨拙了。
我想简而言之,我的问题是我可以在 moc performBlock:^
中调用 dispatch_async(dispatch_get_main_queue()
吗?
基本上
-(void)doTaskwithCompletion:(coreDataCompletion)complete
[self.backgroundManagedObjectContext performBlock:^
// do my BG core data task
[self saveContext:self.backgroundManagedObjectContext];
dispatch_async(dispatch_get_main_queue(), ^
// back to the main thread
);
];
【问题讨论】:
有什么问题?为什么你认为你做不到? 【参考方案1】:我想你知道调用异步内容并在内部返回 mainQueue 是一种非常常见的模式,即用于更新 UI:
dispatch_async(globalQueue, ^
// do something
dispatch_async(mainQueue, ^
// update UI
);
);
由于您已经将变量命名为self.backgroundManagedObjectContext
,因此您可能对Multi-Context CoreData 心存疑虑,我理解您的担忧。只要您不尝试使用此块为 CoreData 更改某些内容(在任何上下文中),您可能就可以了。
只需确保为上下文使用正确的初始化程序,即[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
【讨论】:
是的,这一切都是正确的......我不确定 performBlock 是否被视为 GCD ......但 NSPrivateQueueConcurrencyType 已设置......所以如果它与您的示例基本相同,那么我很高兴!【参考方案2】:“简而言之,我想我的问题是我可以在 moc performBlock:^ 中调用 dispatch_async(dispatch_get_main_queue() 吗?”
答案是肯定的!实际上,当您从主线程调用 performBlock 时,您正在做相反的事情,对吧?这是ios的一个共同特点。一种更简洁的方法可能是传入一个完成,并在该完成中调用 main...
现在,你有:
dispatch_async(dispatch_get_main_queue(), ^
// back to the main thread
completion()
);
你也可以写:
-(void)doTaskwithCompletion:(coreDataCompletion)complete
[self.backgroundManagedObjectContext performBlock:^
// do my BG core data task
[self saveContext:self.backgroundManagedObjectContext];
complete()
];
其中完成了对主线程的调用。
【讨论】:
好的,这样可以吗?伟大的!然后,我的代码中的其他地方出现了奇怪的问题……我会调查的。谢谢!以上是关于NSManagedObjectContext performBlock 内的 dispatch_async(dispatch_get_main_queue()的主要内容,如果未能解决你的问题,请参考以下文章
NSManagedObjectContext:撤消保存操作?
CoreData 多 NSManagedObjectContext 保存通知说明
NSManagedObjectContext: performBlockAndWait vs performBlock 通知中心