首页 > 代码库 > iOS 开发系列:CoreData Object 变成 Fault 的一种方式

iOS 开发系列:CoreData Object 变成 Fault 的一种方式

@quote:

近来一直与 CoreData 打交道,这是一个架构庞大、学习曲线比较陡峭的 iOS 组件,每次遇到问题都会对其有新的认识。

这次就只讲一点,关于错误认知 Object(NSManagedObject)与 Context (NSManagedContext)的引用关系而导致的 Fault 问题。

用过 CoreData 的都应该对其基本使用有个最直接的了解,那就是:Object 都是放在 Context 里的,同时 Object 也会有一个 「managedObjectContext」的方法,可以得到它所在的 Context。

刚开始,我很天然地以为,Context 强引用了 Object,Object 反过来也是引用了 Context。事实上不是如此,Object 的 「managedObjectContext」是 method,而不是 property,这是没有强引用关系的。

假如你从 CoreData Stack 新建了一个 Context,然后从这个 Context 里取出来一个 Object,并且把这个 Object 指派给一个 ViewController,最后在这个 ViewController 里进行一些任务,你很快就会发现,Object 变成 fault 而无法使用了。

这是因为如果不同样强引用这个 Context,在它被释放掉以后,Object 会因为没有这个 Context 而导致「Fault cannot be fulfilled」进而无法使用。

关于「Fault cannot be fulfilled」,在 Apple 官方文档「 Troubleshooting Core Data 」还有一个例子,与我遇到的这个不太一样。它所描述的情况是:从 Context 里删除了 Object 以后,实质内容已经被删除,但 Object 因为在内存管理周期内还没有被释放掉,只是变成了一个 Fault,这时如果再访问这个 Object,就会得到「Fault cannot be fulfilled」的错误。

再回到我遇到的那个问题,通常在一个不是特别复杂的基于 CoreData 的程序当中,我们不会用到很多个 Context,而且大家的 CoreData Stack 都是在 AppDelegate 级别强引用了 Context,尤其不会用到临时新建的 Context 而忘记强引用它,因而这个问题也太不常见。

总之,看文档的时候一定要注意区分 method 和 property,即使使用同样的语法+返回的是同样的东西,也不能觉得它们是一回事。从这里上来看,严格的使用 [object method] 和 object.property 这个语法还是有必要的。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

PS: 我查阅了API文档,上面有句话一直不懂:

- (BOOL)isFault

Description

Returns a Boolean value that indicates whether the receiver is a fault.


Knowing whether an object is a fault is useful in many situations when computations are optional. It can also be used to avoid growing the object graph unnecessarily (which may improve performance as it can avoid time-consuming fetches from data stores).

If this method returns NO, then the receiver‘s data must be in memory. However, if this method returnsYES, it does not imply that the data is not in memory. The data may be in memory, or it may not, depending on many factors influencing caching

If the receiver is a fault, calling this method does not cause it to fire.  ////这句话真心不明白?还请大虾赐教@@ 



iOS 开发系列:CoreData Object 变成 Fault 的一种方式