核心数据多线程违规

时间:2016-06-09 08:47:34

标签: ios multithreading core-data

我收到了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
    }
}

Line of Crash along with thread trace

编辑1:

我缩小了崩溃范围,但我仍然无法找出崩溃的原因。如果我不将结果存储在deletedManagedObjects,insertedOrUpdatedManagedObjects中,则代码可以正常工作。但如果我在NSoperation完成后崩溃了。

编辑2: 添加了崩溃线和线程跟踪的屏幕截图。

1 个答案:

答案 0 :(得分:0)

在调试器中为“All Exceptions”设置断点并再次运行测试。断点在哪里开火?

从您的问题的阅读中,您似乎假设问题就在这里。

究竟是什么行代码抛出异常?

更新1

根据您更新的问题,问题是您正在触摸他们创建的队列之外的.tabs__body--is-hidden实例,这违反了规则。 {{1}}完成后,您对这些对象做了什么?