Core Data的NSPrivateQueueConcurrencyType和在线程之间共享对象 [英] Core Data's NSPrivateQueueConcurrencyType and sharing objects between threads

查看:1093
本文介绍了Core Data的NSPrivateQueueConcurrencyType和在线程之间共享对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆