2017-07-26 90 views
1

我看到我有相同的核心數據堆棧跟蹤應用程序的幾個崩潰報告:的NSManagedObjectContext -save:引起SIGSEGV崩潰

enter image description here

我已經無法重現此崩潰,但我我認爲它與級聯刪除NSManagedObject關係有關。這是通過調用堆棧跟蹤中看到的_propagatePendingDeletesAtEndOfEvent:來判斷的。我NSManagedObjectContext設置如下:

- (NSManagedObjectContext*)managedObjectContext { 
    if (_managedObjectContext == nil) { 
     _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
     [_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; 
    } 
    return _managedObjectContext; 
} 

上可能會造成什麼來-save:來電與我的整個應用該堆棧跟蹤崩潰任何想法?

+0

看起來像數據競賽.. – Michael

回答

1

從堆棧跟蹤我只能看出這是一個競爭條件,更具體在strong屬性或可變數據的比賽,很可能在一本字典。由於崩潰發生在主線程上,我的第一個猜測是你在背景線程上使用了API,而後臺線程不應該訪問它。

  • 爲什麼我認爲這是一場數據競賽?
  • 由於競爭條件,核心數據代碼在主線程上崩潰的最可能原因是什麼?
  • 修復此錯誤的一些建議。

爲什麼我認爲這是一個數據的比賽?

由於墜毀objc_retain發生。這只是經驗。在我看到保留一個對象發生崩潰的10個案例中,有9個是因爲數據競賽。在另外一種情況下,罪魁禍首是手動進行內存管理錯誤。如果您對更多細節感興趣,可以查看objc_storeStrong()的來源。

其次,Concurrency section in the Core Data Reference有這個有趣的信息:

NSMainQueueConcurrencyType是專門爲您的應用程序接口的使用,並且只能在應用程序的主隊列中。

的NSPrivateQueueConcurrencyType配置在初始化時創建自己的隊列,並可以在該隊列中僅使用。由於隊列是NSManagedObjectContext實例的私有和內部隊列,因此只能通過performBlock:和performBlockAndWait:方法訪問該隊列。

由於競爭條件,核心數據代碼在主線程上崩潰的最可能原因是什麼?

根據您問題中的代碼,您正在使用NSMainQueueConcurrencyType,因此核心數據不應該在具有此「託管上下文」的背景隊列上使用。

我的猜測是你正在從某個背景線程調用核心數據API。

固定這個錯誤有幾個建議。

競爭情況並不總是導致崩潰。出於這個原因,這種崩潰有時不容易被重現。然而,所有的東西都不會丟失。

要查看它是否確實是數據競賽,您必須查看完整的崩潰報告。通過崩潰報告,您不僅可以追蹤崩潰的主線程,還可以在崩潰發生時追蹤進程的所有其他線程。 (只需在崩潰報告中搜索「CoreData」)。如果您非常不走運,在任何後臺線程上都不會顯示核心數據API。在這種情況下,你至少應該看到一個有一些「autorelasepoolpop」框架的線程。如果您在後臺堆棧跟蹤中發現了一些「CoreData」幀,請在該堆棧跟蹤中找到指向您的應用代碼的幀。你有罪魁禍首。

爲了進行調試,您可以在任何地方調用幾個assert([NSThread isMainThread]);調用,無論您調用核心數據API。如果因斷言失敗而崩潰,則知道問題出在哪裏。

如果您使用的是Xcode 9,您可能需要嘗試新的「主線程清理程序」(在「診斷程序」下的方案設置中,在同一個面板中還配置了「線程清理程序」。想「暫停問題」)。如果這不起作用,請嘗試使用「線程清潔劑」。

您也可以將併發類型切換爲NSPrivateQueueConcurrencyType。請確保將所有核心數據API調用與performBlock:performBlockAndWait:調用包裝在一起,否則您將不會獲得更少的崩潰,但會導致更多的崩潰。如果您確實需要使用來自後臺隊列的核心數據,則可以採用這種方式。出於性能原因。

如果幸運的話,這只是一個小小的代碼錯誤,可以在10分鐘內修復:-)。如果你非常不走運,應用程序的併發架構就會崩潰,你必須(重新)設計它: - /。

希望這會有所幫助。

+0

感謝這是非常有益的。我會研究這些建議。 – hgwhittle

相關問題