2014-10-07 31 views
2

雖然我的一個NSManagedObjectContext正在運行其performBlock用戶已選擇退出其帳戶(這將重置所有上下文和刪除持久性存儲)。該復位代碼顯然是被在相似的時間爲performBlock運行,因此應用程序崩潰與例外:iOS 8應用程序崩潰時重置我的NSManagedObjectContext,而在performBlock

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Object's persistent store is not reachable from this NSManagedObjectContext's coordinator'

它崩潰的準確位置似乎是當一個上下文在其performBlock撲救,然後它會發出did save通知,併合併到其他上下文中。這裏是堆棧跟蹤:

0 CoreFoundation      0x03b96df6 __exceptionPreprocess + 182 

1 libobjc.A.dylib      0x03820a97 objc_exception_throw + 44 

2 CoreData       0x034f7791 _PFRetainedObjectIDCore + 1169 

3 CoreData       0x034f72f0 -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:] + 32 

4 CoreData       0x034db0f3 -[NSManagedObjectContext objectWithID:] + 595 

5 CoreData       0x0352e14e _faultBatchAtIndex + 1102 

6 CoreData       0x0352ed02 -[_PFBatchFaultingArray objectAtIndex:] + 50 

7 CoreData       0x035dd010 +[NSFetchedResultsController(PrivateMethods) _insertIndexForObject:inArray:lowIdx:highIdx:sortDescriptors:] + 144 

8 CoreData       0x035d7ba2 -[NSFetchedResultsController(PrivateMethods) _postprocessInsertedObjects:] + 738 

9 CoreData       0x035da3dd __77-[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:]_block_invoke + 2285 

10 CoreData       0x034e7454 developerSubmittedBlockToNSManagedObjectContextPerform + 196 

11 CoreData       0x034e7337 -[NSManagedObjectContext performBlockAndWait:] + 231 

12 CoreData       0x035d9acf -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] + 127 

13 Foundation       0x00eff929 __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke + 40 

14 CoreFoundation      0x03b61974 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20 

15 CoreFoundation      0x03a4f61b _CFXNotificationPost + 3051 

16 Foundation       0x00eeef26 -[NSNotificationCenter postNotificationName:object:userInfo:] + 98 

17 CoreData       0x034c84d3 -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 83 

18 CoreData       0x034d9cbe -[NSManagedObjectContext _mergeChangesFromDidSaveDictionary:usingObjectIDs:] + 3934 

19 CoreData       0x034d8d40 -[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:] + 496 

20 App        0x00319707 __57-[ContextManager contextDidSavePrivateQueueContext:]_block_invoke + 103 

這是僅iOS 8 - iOS 7正常工作。我無法弄清楚的是,如果這是iOS 8的一個錯誤,我感受到了影響,或者Apple已經將「新功能」引入了Core Data中,這已經打破了我們的重置流程。任何人都可以對此有所瞭解嗎?

+0

「我的一個NSManagedObjectContext」。這似乎表明你有不止一個。他們是親子還是同齡人? – quellish 2014-10-08 14:59:05

+0

一個是私人的,一個是主要的。沒有父母/子女。 – Harry 2014-10-08 15:32:01

+0

如果你正在使用隊列封閉,你應該使用親子,否則你會看到像這樣的問題。 – quellish 2014-10-08 15:41:56

回答

1

我通過NSManagedObjectContext添加類別和使用objc_setAssociatedObject魔法把一個標誌固定的bug。該標誌是用於執行任何執行塊的上下文是否安全。爲此,我在名爲safePerformBlock的類別中添加了另一種方法,該類別查看該標誌。如果是假的,我立即返回了,而不是處理中傳遞塊。

當我刪除上下文的持久性存儲,該標誌設置爲不安全。當用戶重新登錄並重新創建持久性存儲時,該標誌被設置爲安全。

本質上講,我對上下文的performBlocks取消令牌處理此標誌。爲什麼API中沒有這個我不知道的東西。在這種情況下,這是我能找到的最佳解決方案。

0

核心數據不是線程安全的。一個NSManagedObjectContext只能在創建它的線程中使用。一旦持久性商店消失,就不能使用它。 iOS 8中的時機很有可能會有所不同,但由於您無法依賴時機,因此它可能總是您代碼中的一個錯誤。

+0

正如海報指出的那樣,他正在使用帶有performBlock的隊列限制,它可以安全地從任何線程調用。 – quellish 2014-10-08 14:59:36

0

你可以把復位操作在同一個線程比你performBlock,把隊列中「無conccurency」模式。所以只有當performBlock結束時纔會發生重置。