在多个线程上读/写自定义对象

时间:2016-01-12 23:33:32

标签: multithreading swift core-data grand-central-dispatch nsmanagedobject

我需要能够从Core Data中获取对象并将它们保存在内存中的可变数组中,以避免不断获取和降低UI / UX。问题是我抓住了其他线程上的对象。我也有时在其他线程上写这些对象。因此,我不能将NSManagedObjects保存在数组中,只需调用类似myManagedObjectContext.performBlockmyObject.managedObjectContext.PerformBlock的内容,因为您不应该在线程之间传递MOC。

我正在考虑使用自定义对象将我需要的数据从CD对象中抛出。这感觉有点愚蠢,因为我已经为实体创建了Model / NSManagedObject类,并且因为自定义对象是可变的,所以它仍然不是线程安全的。这意味着我必须为多个线程上的对象操作执行类似串行队列的操作?因此,例如,任何时候我想读/写/删除一个对象,我必须把它扔进我的对象serialQueue。

这一切看起来真的很讨厌所以我想知道这个问题有什么常见的设计模式或类似的东西吗?有没有更好的方法呢?

2 个答案:

答案 0 :(得分:5)

我怀疑您需要Core Data和UI之间的自定义对象。有一个更好的答案:

  1. 您的UI应该从与主线程相关联的托管对象中读取(听起来就是这样)。
  2. 当您在另一个线程上进行更改时,这些更改将更新主线程上的对象。这就是Core Data的目的。
  3. 您只需要听取这些更改并让您的UI对它们做出反应。
  4. 有几种方法可以做到这一点:

    • NSFetchedResultsController。有点像你的可变数组,但有一个委托,它会在对象发生变化时通知。强烈推荐
    • 侦听您在UI中显示的属性上的KVO更改。每当属性发生变化时,您都会收到KVO通知并对其做出反应。更多的代码,但也更集中。
    • 通过NSManagedObjectContextDidSaveNotification中心收听NSNotification个事件,并对通知作出反应。正在更改的对象将位于通知的userInfo中。

    在这三个中,使用NSFetchedResultsController通常是正确的答案。当它到位时,您只需更改其他线程上需要更改的内容,保存上下文即可完成。用户界面将自行更新。

答案 1 :(得分:-2)

一种模式是仅传递对象id,它们是NSString个对象,不可变且因此线程安全,并且在这些id之后在主线程上进行查询。这样,每个NSManagedObject都属于相应的线程。

或者,您可以使用mergeChangesFromContextDidSaveNotification来更新主线程中的对象以及在辅助线程上所做的更改。但是,您仍然需要获取新对象。

“警告”是您需要保存辅助上下文才能获得这样的通知。在应用合并后,任何新创建但未保存的主线程对象都将丢失 - 但是如果主线程仅使用CoreData个对象,则可能不会出现问题。