@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 returns YES, 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. ////這句話真心不明白?還請大蝦賜教@@