属性延迟初始化vs Core Data在主线程中运行

时间:2016-04-25 12:04:38

标签: ios objective-c multithreading core-data

我有一个属性:

@property (strong, nonatomic) NSArray *emails;

和它的懒惰初始化程序

- (NSArray *) emails
{
    if (_emails == nil) {
        CoreDataElement* cde = [user grabCoreDataElement];
        _emails = [cde.emails allObjects];
    }
    return _emails;
 }

然而,在代码审查期间,有人指出应该在主线程中访问核心数据。

所以我在考虑将初始化程序修改为:

- (NSArray *) emails
{
    if (_emails == nil) {
        if (NSThread isMainThread])
        {
            CoreDataElement* cde = [user grabCoreDataElement];
            _emails = [cde.emails allObjects];
        }
        else
        {
            __block NSArray *result = nil;
            dispatch_sync(dispatch_get_main_queue(), ^{
                result = self.emails;
            });
            return result;
        }
    }
    return _emails;

}

所以我的问题是:

  • (1)是否需要强制执行MainThread?
  • (2)上面的代码是否是处理延迟初始化器和核心数据对象访问的规范方法?

1 个答案:

答案 0 :(得分:2)

这些都不对。如果您正在使用Core Data并且可能在多个线程上运行代码,那么正确的方法是在创建托管对象上下文时使用NSMainQueueConcurrencyTypeNSPrivateQueueConcurrencyType,然后使用{只要您执行访问Core Data的任何操作,就会{1}}或performBlock:。检查performBlockAndWait:或使用NSThread最初可能不会中断,但都违反了Core Data对其应如何运作的想法。

使用这种方法,您的方法中的代码将包含在对dispatch_syncperformBlock:的调用中,但并非全部。每次以任何方式访问Core Data时都需要使用这些方法 - 因此,如果要返回托管对象数组,则在查找这些对象的值时需要使用相同的块调用。