美文网首页
iOS CoreData多线程安全

iOS CoreData多线程安全

作者: williamhlw | 来源:发表于2020-05-18 12:11 被阅读0次

为何使用多线程


    在开发中使用到了CoreData,虽然实例化NSManagedObjectContext的时候提供了三种方法:

NSConfinementConcurrencyType(iOS 9废弃)

NSPrivateQueueConcurrencyType

NSMainQueueConcurrencyType

NSManagedObjectContext提供的多线程执行方法:

-(void)performBlock:(void(^)())blockNS_AVAILABLE(10_7,5_0);

-(void)performBlockAndWait:(void(^)())blockNS_AVAILABLE(10_7,5_0);

但在实际使用中,如果线程方法有问题,一样可能会导致数据库读写操作等问题,比如读写同时操作导致数据源为空等。找了很多文档,分享下使用方案。


多线程方案

    通过建立上下文间的父子关系,避免上下文的合并操作。

子上下文的改动保存时会提交给父上下文,最后由根部的上下文提交所有改动给PSC。因此建立关系之后,上下文的改动就不需要用通知去告知其他上下文了。我们可以通过设置如下属性来设置父上下文。

使用三层的MOC去实现多线程Core Data,privateContext -> mainContext -> rootContext

其中privateContext用于执行操作,mainContext用于与UI协作,rootContext用于在后台保存所有子上下文的提交。

存在的问题

MO都有唯一的MOID与之对应,为了避免实例化MO时消耗大量资源来确保ID的唯一性,所以MO在实例化时会被给予一个临时的ID,这个ID在MOC范围内唯一。当MOC进行提交时,需要将临时ID转化为全局ID,所以我们需要监听MOC将要保存的通知来处理MOID的转换:

// 上下文将要提交保存的通知

nameNSManagedObjectContextWillSaveNotification

// MOID转换方法

- (BOOL)obtainPermanentIDsForObjects:(NSArray *)objects error:(NSError**)errorNS_AVAILABLE(10_5,3_0);

方案二初始化:

CoreDataManager.m:

增:

删:

改:

查:


总结

    在一般的数据库操作时,数据修改放在privateContext异步执行,数据查询放在MainContext同步执行,保证数据正确。但是特殊的情况(比如我遇到的项目),所有操作必须要在启动数据库修改完成后执行,那么数据库修改要放到MainContext执行。

相关参考链接:链接

相关文章

网友评论

      本文标题:iOS CoreData多线程安全

      本文链接:https://www.haomeiwen.com/subject/txhuohtx.html