簡體   English   中英

核心數據隨機崩潰,可能存在並發問題

[英]Random crash with core data, possible concurrency issue

我有一段代碼,它首先清空核心數據表,然后用新的和更新的數據填充它。 這段代碼位於DispatchQueue.main.async塊中,該塊在異步請求完成后發生。 這是功能中的相關代碼。

這是我的代碼:

let queue = OperationQueue()
let deleteOperation = BlockOperation {
    let fetchRequest = Track.fetchRequest()

    let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
    batchDeleteRequest.resultType = .resultTypeCount

    do {
        try self.managedObjectContext.execute(batchDeleteRequest)
        self.managedObjectContext.reset()
    }
    catch {
        fatalCoreDataError(error)
        self.debug.log(tag: "RecentSessionsViewController", content: "Failed to delete cache")
        return
    }
}

let addOperation = BlockOperation {
    for track in tempTracks {
        let masterListEntry = NSEntityDescription.insertNewObject(forEntityName: "Track", into: self.managedObjectContext) as! Track

        masterListEntry.id = track["id"] as! NSNumber
        masterListEntry.name = track["name"] as! String
        masterListEntry.comment = track["comment"] as! String

        do {
            try self.managedObjectContext.save()

            self.trackMasterList.append(masterListEntry)
        }
        catch {
            self.debug.log(tag: "RecentSessionsViewController", content: "Core data failed")
            fatalError("Error: \(error)")
        }
    }
}

addOperation.addDependency(deleteOperation)
queue.addOperations([deleteOperation, addOperation], waitUntilFinished: false)

由於某種原因,我有時會在代碼的addOperation塊上出現隨機崩潰。 在最近的崩潰中,在以下位置觸發了異常斷點:

try self.managedObjectContext.save()

如果我單擊繼續,它將再次落在此斷點上,然后當我再次單擊繼續時,它將崩潰,並顯示匯編和以下錯誤:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: attempt to insert nil'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010c70f34b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x000000010bd5321e objc_exception_throw + 48
    2   CoreFoundation                      0x000000010c778265 +[NSException raise:format:] + 197
    3   CoreFoundation                      0x000000010c6a762b -[__NSCFSet addObject:] + 155
    4   CoreData                            0x000000010c2427ff -[NSManagedObjectContext(_NSInternalChangeProcessing) _processPendingUpdates:] + 399
    5   CoreData                            0x000000010c23cccd -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 2445
    6   CoreData                            0x000000010c240e0c -[NSManagedObjectContext save:] + 412
    7   AppName                            0x000000010b0db7eb _TFFFFC8AppName28RecentSessionsViewController22refreshListFT_T_U_FTGSqV10Foundation4Data_GSqCSo11URLResponse_GSqPs5Error___T_U_FT_T_U0_FT_T_ + 6459
    8   AppName                            0x000000010b086987 _TTRXFo___XFdCb___ + 39
    9   Foundation                          0x000000010b8572cd __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
    10  Foundation                          0x000000010b856faf -[NSBlockOperation main] + 101
    11  Foundation                          0x000000010b8556ac -[__NSOperationInternal _start:] + 672
    12  Foundation                          0x000000010b8515ef __NSOQSchedule_f + 201
    13  libdispatch.dylib                   0x00000001134100cd _dispatch_client_callout + 8
    14  libdispatch.dylib                   0x00000001133ede6b _dispatch_queue_serial_drain + 236
    15  libdispatch.dylib                   0x00000001133eeb9f _dispatch_queue_invoke + 1073
    16  libdispatch.dylib                   0x00000001133f13b7 _dispatch_root_queue_drain + 720
    17  libdispatch.dylib                   0x00000001133f108b _dispatch_worker_thread3 + 123
    18  libsystem_pthread.dylib             0x00000001137bf746 _pthread_wqthread + 1299
    19  libsystem_pthread.dylib             0x00000001137bf221 start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException

在過去,我還看到它崩潰並出現以下錯誤:“在上下文中止時嘗試遞歸調用-save:”。

有什么想法嗎? 我將這些內容包裝到NSOperation塊中的全部原因是為了防止這種情況。 顯然這沒有用。 這是零星的,所以我不確定它是否已解決。

我猜發生了什么事,當它試圖寫入數據時,它仍在刪除數據的過程中。

您沒有正確執行Core Data並發。 正確的方法是在NSManagedObjectContext上使用performperformAndWait方法。 像代碼一樣在操作隊列中使用上下文是解決與並發相關的錯誤的訣竅。

派遣隊列對您沒有幫助。 您仍然可以使用調度隊列,但是還必須使用Core Data的並發方法來避免問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM