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

Posted

技术标签:

【中文标题】属性延迟初始化 vs Core Data 在主线程中运行【英文标题】:Property lazy initialization vs Core Data run in main thread 【发布时间】:2016-04-25 12:04:37 【问题描述】:

我有一个财产:

@property (strong, nonatomic) NSArray *emails;

还有一个惰性初始化器

- (NSArray *) emails

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

然而,在代码审查期间,有人指出对 Core Data 的访问应该在主线程中完成。

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

- (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】:

这些都不对。如果您使用 Core Data 并且可能在多个线程上运行代码,那么正确的做法是在创建托管对象上下文时使用 NSMainQueueConcurrencyTypeNSPrivateQueueConcurrencyType,然后使用 performBlock: 或 @ 987654324@ 每当你做任何访问核心数据的事情时。检查NSThread 或使用dispatch_sync 一开始可能不会中断,但两者都违反了Core Data 关于它应该如何工作的想法。

使用这种方法,您方法中的代码将封装在对performBlock:performBlockAndWait: 的调用中,但这还不是全部。您需要在任何时候以任何方式访问 Core Data 时使用这些方法——因此,如果您要返回托管对象数组,则在查找这些对象的值时需要使用相同的块调用。

【讨论】:

以上是关于属性延迟初始化 vs Core Data 在主线程中运行的主要内容,如果未能解决你的问题,请参考以下文章

Core Data 可以在 iOS 上延迟获取 BLOB 属性吗?

Core Data 托管对象上下文线程同步

Core Data 3 托管对象上下文

Core Data 似乎没有采用更新的值

好的教程或适合在 IOS 7 中使用 Core.Data [关闭]

Vue.js线程机制问题还是数据双向绑定有延迟的问题