NSManagedObjectContext.performBlockAndWait()在主线程/队列上运行块

时间:2016-06-02 10:51:55

标签: ios swift multithreading core-data concurrency

print("queue1: \(NSOperationQueue.currentQueue())")
managedObjectContext.performBlockAndWait({
    print("queue2: \(NSOperationQueue.currentQueue())")
})

,输出为:

queue1: Optional(<NSOperationQueue: 0x7fa31c030cf0>{name = 'NSOperationQueue 0x7fa31c030cf0'})
queue2: Optional(<NSOperationQueue: 0x7fa319d114d0>{name = 'NSOperationQueue Main Queue'})

因此,performBlockAndWait在主线程中运行块。不知道为什么? 这是预期的行为吗?

所以,任何问题的解决方案:

  1. 我需要在后台运行块的代码,否则会冻结UI。那么,我怎么能?,
  2. 如果我没有使用performBlockAndWait块崩溃中的代码与描述Terminating app due to uncaught exception NSInvalidArgumentException, reason _referenceData64 only defined for abstract class。还有其他选择吗?

2 个答案:

答案 0 :(得分:1)

PerformBlock()和performBlockAndWait()在创建上下文的队列上运行。因此,如果您的managedObjectContext是在主队列中创建的,它将在主队列中运行。

如果您想要后台执行,则需要创建背景上下文:

let privateContext = NSManagedObjectContext(
  concurrencyType: .PrivateQueueConcurrencyType)

privateContext.persistentStoreCoordinator = mainQueueContext.persistentStoreCoordinator

privateContext.performBlock {
...
}

答案 1 :(得分:0)

使用完成处理程序在单独的函数中执行您要在后台执行的任务。

       dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
        func performFuncWithCompletion() { (Success) in
              if (Success)
                  NSOperationQueue.mainQueue().addOperationWithBlock {
                      // update UI here
                  }
               else {  
                       // Show error message?
                    }
           }  
  }


 func performFuncWithCompletion(completion : (SuccessStatus: Bool)) {
        // perform your back ground function here.
        // Decide if everything went fine
       if everythingWentFine {
           completion(true)
        }
       else {
            completion(false)
            }
}

询问是否有任何问题