iOS Core data多線程並發訪問的問題


大家都知道Core data本身並不是一個並發安全的架構;不過針對多線程訪問帶來的問題,Apple給出了很多指導;同時很多第三方的開發者也貢獻了很多解決方法。不過最近碰到的一個問題很奇怪,覺得有一定的特殊性,與大家分享一下。

這個問題似乎在7.0.1以前的版本上並不存在;不過后來我升級版本到了7.0.4。app的模型很簡單,主線程在前台對數據庫進行讀寫,而后台線程不斷地做掃描(只讀)。為此每個線程中各創建了一個NSManagedObjectContext。

這個模型其實有點奇怪,因為普遍的模型是顛倒過來的——后台線程做讀寫更新,而主線程只讀;但是由於我的app的特殊性,並且讀寫性能並不關鍵,所以我並不想花很大力氣去扭曲邏輯自然的結構,還是保持這個模型。不過問題也因此而來:我發現主線程寫入的數據,后台線程讀出來的並不一致,而是寫入之前的值,即使我重新做了完整的fetch。

按照Apple文檔和其他第三方資料的說明,主程序用context save后,這個改動就一定被persistent了;那么后台線程fetch怎么可能讀出以前的值?機器是不會錯的,既然讀出的是以前的值,那么肯定是后台線程的context在哪里cache了一份。但是fetch操作無論如何應該返回persistent store里的值啊?而且insert/delete操作的修改,確實都反應出來了,唯有對property值的修改,還是舊的數值;

大量的有關並發問題的第三方討論文章顯示的是相反的問題:如果在后台線程做了修改,那么需要merge到主線程。但是這個merge影響到的只是NSFetchResultsController的內容,對於不merge造成的后果,所有的文章都眾口一詞:除非re-fetch或者re-fault,否則數據當然會不一致。也就是說,如果re-fetch,那么數據還是可以保持一致的。然而實際的測試證明即使是re-fetch了,還是無法反應change的數值。

最終只能懷疑re-fetch仍然不是徹底地從persistent storage里面重新load整個model。雖然insert/delete的對象確實重新load了,但是change的property確確事實沒有被更新;NSManagedObjectContext 對fetch實現的機制,應該還是在內存里留了一份model的cache。為了徹底清楚這個cache,對后台線程的context進行reset后,果然一切都正常了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM