【发布时间】:2016-06-09 08:47:33
【问题描述】:
我遇到了 Core Data 多线程违规问题。即使我使用performBlockAndWait。我有一个NSOperation 子类来执行云套件的 BG 提取。下面是代码。它在所有执行完成后崩溃。
override public func main() {
self.localStoreMOC?.performBlockAndWait({ () -> Void in
do
{
try self.fetchTest()
self.syncCompletionBlock!(syncError: nil)
}
catch let error as NSError
{
let userInfo:Dictionary<String, AnyObject> = [CKSIncrementalStoreError: error];
let error1 = NSError(domain: CKSIncrementalStoreSyncOperationErrorDomain, code: CKSErrorCode.CKSErrorDatabaseError.rawValue, userInfo: userInfo)
self.syncCompletionBlock!(syncError: error)
}
})
}
func fetchTest() throws
{
let predicate = NSPredicate(format: "%K != %@", CKSIncrementalStoreLocalStoreChangeTypeAttributeName, NSNumber(short: CKSLocalStoreRecordChangeType.RecordNoChange.rawValue))
var deletedManagedObjects:Array<AnyObject> = Array<AnyObject>()
var insertedOrUpdatedManagedObjects:Array<AnyObject> = Array<AnyObject>()
let fetchRequest = NSFetchRequest(entityName: self.entityNames1.objectAtIndex(self.tableIndex) as! String)
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "modifiedDateL", ascending: false)]
fetchRequest.predicate = predicate
fetchRequest.fetchOffset = self.fetchOffset
fetchRequest.fetchLimit = self.batchSize
var results: [AnyObject]?
do
{
results = try self.localStoreMOC?.executeFetchRequest(fetchRequest)
if results != nil && results?.count > 0
{
insertedOrUpdatedManagedObjects += (results!.filter({(object)->Bool in
let managedObject:NSManagedObject = object as! NSManagedObject
if (managedObject.valueForKey(CKSIncrementalStoreLocalStoreChangeTypeAttributeName)) as! NSNumber == NSNumber(short: CKSLocalStoreRecordChangeType.RecordUpdated.rawValue)
{
return true
}
if (managedObject.valueForKey(CKSIncrementalStoreLocalStoreChangeTypeAttributeName)) as! NSNumber == NSNumber(short: CKSLocalStoreRecordChangeType.RecordInserted.rawValue)
{
return true
}
return false
}))
deletedManagedObjects += (results!.filter({(object)->Bool in
let managedObject:NSManagedObject = object as! NSManagedObject
if (managedObject.valueForKey(CKSIncrementalStoreLocalStoreChangeTypeAttributeName)) as! NSNumber == NSNumber(short: CKSLocalStoreRecordChangeType.RecordDeleted.rawValue)
{
return true
}
return false
}))
self.totalItems = insertedOrUpdatedManagedObjects.count + deletedManagedObjects.count
self.fetchOffset = self.fetchOffset + self.batchSize
print("totalItems : \(self.totalItems) fetchOffset : \(self.fetchOffset) results \(results)")
if self.totalItems < self.defaultBatchSize
{
self.batchSize = self.defaultBatchSize - self.totalItems
}
}
else
{
self.tableIndex++
self.fetchOffset = 0
}
}
catch let error1 as NSError
{
insertedOrUpdatedManagedObjects.removeAll()
deletedManagedObjects.removeAll()
results = nil
throw error1
}
}
编辑1:
我缩小了崩溃的范围,但我仍然无法找出崩溃的原因。如果我不将结果存储在deletedManagedObjects、insertedOrUpdatedManagedObjects 中,则代码可以正常工作。但是如果我这样做,它会在 NSoperation 完成后崩溃。
编辑 2: 已添加崩溃行和线程跟踪的屏幕截图。
【问题讨论】:
-
确保您已通读核心数据和并发中的以下内容:developer.apple.com/library/content/documentation/Cocoa/…
标签: ios multithreading core-data