[英]Coredata concurrency issues
我有一個具有私有上下文的NSOperation子類,以及一個在主隊列上具有上下文的單例數據管理器類。 所有的UI和操作操作都由該單例類完成,而從雲工具包中進行的后台獲取則由NSOperation子類完成。 幾乎沒有什么疑問,如下所示。
以下是我在NSoperation子類中擁有的代碼。下面的代碼可以創建死鎖嗎?
self.localStoreMOC?.performBlockAndWait({ () -> Void in //Long process of fetching data from cloud and pushing changes to cloud happens here. var error:NSErrorPointer = nil if self.localStoreMOC!.hasChanges { do { try self.localStoreMOC!.save() } catch let error1 as NSError { error.memory = error1 } if error == nil { self.localStoreMOC!.parentContext!.performBlockAndWait({ do { try self.localStoreMOC!.parentContext!.save() } catch let error1 as NSError { print("wasSuccessful error1 \\(error1)") } }) } } }
如果我還有另一個使用此類的單例類NSManagedOBject,我需要通過ID傳遞它們嗎?
首先,您需要在運行時參數中打開-com.apple.CoreData.ConcurrencyDebug 1
。 這將有助於確保您在正確的線程/隊列上調用所有內容。
其次,您要對可選選項進行很多強制拆包,這是一個非常不好的習慣。最好正確地對其進行拆包或使用可選拆包。
第三,當您暫停調試器時會發生什么? 暫停的代碼行在哪里,您在什么隊列上?
僅打開並發調試將很可能向您顯示問題。
如果你是想傳遞給一個參考NSManagedObject
從一個環境到另一個則是,你需要使用NSManagedObjectID
作為NSManagedObject
是不安全的上下文之間傳遞。
有點格式化,您可能會對結果感興趣:
guard let local = localStoreMOC else { fatalError("Local store is nil") }
guard let parent = local.parentContext else { fatalError("Parent store is nil") }
local.performBlockAndWait {
//Long process of fetching data from cloud and pushing changes to cloud happens here.
if !local.hasChanges { return }
do {
try local.save()
parent.performBlockAndWait {
do {
try parent.save()
} catch {
print("wasSuccessful error1 \(error)")
}
}
} catch {
print("Failed to save local: \(error)")
}
}
這消除了對可選組件的強制拆包,並且在兩種情況下都輸出了兩個時,會打印出兩個錯誤。
另外,一些開發人員說,像上面那樣嵌套的performblockandwait會導致死鎖。
performBlockAndWait
將永遠不會導致死鎖。 比這更聰明。
performBlockAndWait
則該調用實際上將是無操作的,並且不會死鎖
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.