从Core Data中执行删除、插入和获取操作的正确线程

6
我的应用程序连接到一个 web 服务,从三个不同的方法执行 POST,并将这三组数据中的每一组插入到 Core Data 中。每当新数据可用时,Core Data 中的所有内容都会被删除,并插入新数据。这三种方法中的每一种在不同的 TableViewController 中显示,这意味着每次显示每个 TableViewController 时都会有超过 3 次的获取操作。
总之,我们有 3 组数据从 web 服务获取,并将它们插入到不同的实体中,同时还要获取新数据以在主 TableViewController 中显示。
现在我正在处理线程和多上下文 Core Data 结构之间的复杂关系。为了确保我的应用程序的线程安全性,我应该在哪里执行插入、删除和获取操作?

你有多少数据?你目前有哪些上下文和线程? - Wain
@Wain 数据相对较小,每个实体大约有一千条记录。NSURLSession 在主线程上使用 completionhandler 进行工作。然后它调用一个方法来删除(在主线程 NSMainQueueConcurrencyType 上完成)和插入(主线程/NSPrivateQueueConcurrencyType)。接下来是在主线程和主上下文中进行的获取。 - Rashid
2个回答

4

请在主线程从主上下文中进行UI数据的获取。

对于导入操作,请不要在主线程上运行session回调,而是在任何后台队列上运行。创建一个新的私有上下文,并将其设置为主上下文的子级。在session回调中使用块接口导入和保存后台上下文以及其父级(再次使用块接口)。


我们曾尝试在后台线程上调度会话回调并在主线程上继续插入,但是我们遇到了几个与MainContext上的SaveContext相关的问题。你所说的“使用块接口导入”是什么意思?我没有完全理解你的意思。 - Rashid
这会导致主线程被阻塞,同时在向核心数据插入数据时UI不响应。我认为删除和插入操作应该在另一个线程上执行。但是当我这样做时,获取的数据有时会错误,并且有像未完全执行获取操作的情况。 - Rashid
我的答案建议在后台线程上运行它们,并设置您的上下文,以便更改可以轻松地传递到UI。 - Wain
以这种方式:删除1插入1,删除2插入2,删除3插入3,而在这些操作发生时,每个实体都会执行获取操作。您认为使用两个持久存储库来解决这个问题是一个好方法吗?我很困惑。 - Rashid
触发获取的是什么?如果您没有保存并且获取是自动发生的,则您正在处理错误的上下文... - Wain
显示剩余3条评论

1
在多上下文 CoreData 中,您可以拥有一个 privateQueueRootMOC 和一个 mainQueueRootMoc,主 MOC 用于在主线程中获取数据,私有 MOC 用于在私有 MOC 线程中更新、插入和删除数据。
privateMOC.performBlock({ () -> Void in
    //try insert, delete, update
    ....
    try privateMOC.save()
    onCompleteBlock() //fetch data in main thread use main MOC
})

现在我已经将插入和删除操作移动到了私有MOC的执行块中,看起来一切都正常。但是有一个问题,当我刷新所有内容(连接到Web服务,从核心数据中删除和插入),然后执行获取操作时,它会返回几秒钟的nil。似乎在插入新数据之前,删除操作已经保存在主上下文中了。 - Rashid
在主MOC中,您应该在privateMOC.save()之后添加一个完整的回调块,并使用主MOC从主线程读取数据。或者您可以在主MOC中使用NSFetchResultController来观察CoreData中的数据变化。 - Hao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接