Core Data的NSPrivateQueueConcurrencyType和在线程之间共享对象 [英] Core Data's NSPrivateQueueConcurrencyType and sharing objects between threads
问题描述
iOS 5引入了一种新方法,通过使用 NSPrivateQueueConcurrencyType
初始化MOC,然后在 performBlock中进行提取,从而快速获取后台线程上的数据:
Core Data的一个规则是,您不能在线程/队列之间共享受管对象。是否仍然是 performBlock:
?是以下:
[context performBlock:^ {
//提取请求代码
$ b b NSArray * results = [context executeFetchRequest:request error:nil];
dispatch_async(dispatch_get_main_queue(),^(void){
Class * firstObject = [results objectAtIndex:0];
// using something with firstObject
} ;
}];
仍然不能接受,因为我在bg队列和主队列之间共享我的结果数组/对象?当你使用 NSPrivateQueueConcurrencyType
当你使用 / code>您需要在
-performBlock:$>中执行触及该上下文或的任何 c $ c>方法。
您的代码是非法的,因为您将这些对象传递回主队列。新的API帮助你解决这个问题:你创建一个与主队列相关联的上下文,即 NSMainQueueConcurrencyType
:
$ b $
NSManagedObjectContext * mainMOC = [[[NSManagedObjectContext alloc]] initWithConcurrencyType: NSMainQueueConcurrencyType] autorelease];
NSManagedObjectContext * backgroundMOC = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];
//现在可以从任何线程安全地调用:
[backgroundMOC performBlock:^ {
NSArray * results = [backgroundMOC executeFetchRequest:request error:nil];
for(NSManagedObject * mo in results){
NSManagedObjectID * moid = [mo objectID];
[mainMOC performBlock:^ {
NSManagedObject * mainMO = [mainMOC objectWithID:moid];
//用'mainMO'做东西。注意不要使用'mo'。
}];
}
}];
如果你移动内部 [mainMOC performBlock:]
调用进入自己的方法。您还可能想要将对象ID的数组传递回主线程的上下文,而不是为每个对象ID执行一个块。这取决于你的需要。
iOS 5 introduced a new way to quickly fetch data on a background thread by initializing the MOC using NSPrivateQueueConcurrencyType
and then doing the fetch in performBlock:
One of the rules of thumb of Core Data has been that you can not share a managed object between threads/queues. Is it still the case with performBlock:
? Is the following:
[context performBlock:^{
// fetch request code
NSArray *results = [context executeFetchRequest:request error:nil];
dispatch_async(dispatch_get_main_queue(), ^(void) {
Class *firstObject = [results objectAtIndex:0];
// do something with firstObject
});
}];
still unacceptable since I'm sharing my results array/objects between the bg queue and the main queue? Do I still need to use the managed object IDs to do that?
When you use NSPrivateQueueConcurrencyType
you need to do anything that touches that context or any object belonging to that context inside the -performBlock:
method.
Your code above is illegal since you're passing those objects back to the main queue. The new API helps you in solving this, though: You create one context that's associated with the main queue, i.e. with NSMainQueueConcurrencyType
:
// Assume we have these two context (They need to be set up. Assume they are.)
NSManagedObjectContext *mainMOC = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType] autorelease];
NSManagedObjectContext *backgroundMOC = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];
// Now this can safely be called from ANY thread:
[backgroundMOC performBlock:^{
NSArray *results = [backgroundMOC executeFetchRequest:request error:nil];
for (NSManagedObject *mo in results) {
NSManagedObjectID *moid = [mo objectID];
[mainMOC performBlock:^{
NSManagedObject *mainMO = [mainMOC objectWithID:moid];
// Do stuff with 'mainMO'. Be careful NOT to use 'mo'.
}];
}
}];
This gets less confusing if you move the inner [mainMOC performBlock:]
call into its own method. You may also want to pass an array of object IDs back to the main thread's context in stead of executing a block for each object ID. It depends on your needs.
这篇关于Core Data的NSPrivateQueueConcurrencyType和在线程之间共享对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!