2016-06-02 3 views
0
print("queue1: \(NSOperationQueue.currentQueue())") 
managedObjectContext.performBlockAndWait({ 
    print("queue2: \(NSOperationQueue.currentQueue())") 
}) 

и выходе:NSManagedObjectContext.performBlockAndWait() запускает блок на основной нити/очереди

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. Любая альтернатива?
+0

Весь смысл 'performBlockAndWait' ** является то, что он ждет **. Даже если он управляет блоком в другом потоке, код, который вызывает 'performBlockAndWait', все еще будет ** ждать ** до тех пор, пока блок не закончится - это означает, что ваш пользовательский интерфейс ** все равно ** перестанет отвечать на запросы во время его выполнения. –

ответ

0

PerformBlock() и performBlockAndWait() работает на очереди, в которой создается контекст вашего. Поэтому, если ваш managedObjectContext создается в главной очереди, он будет запущен в основной очереди.

Если вы хотите выполнение фона необходимо создать фоновый контекст:

let privateContext = NSManagedObjectContext(
    concurrencyType: .PrivateQueueConcurrencyType) 

privateContext.persistentStoreCoordinator = mainQueueContext.persistentStoreCoordinator 

privateContext.performBlock { 
... 
} 
+0

И должен ли я использовать одиночный «managedObjectContext» во всем приложении, или я могу создать его, когда потребуется? –

+0

Для большинства случаев достаточно одного управляемого объекта mainObjectContext. Вы можете создать новый фоновый контекст, если у вас много данных, например, для вставки в основные данные и не может блокировать ui. – stefos

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) 
      } 
} 

Спросите, если какие-либо вопросы

+0

Да, я тоже это пробовал. Но столкнулся с исключением выше (в пункте 2 вопроса) –

+0

Какое исключение и на какой строке? –

+0

Однократное приложение из-за неперехваченного исключения NSInvalidArgumentException, причина _referenceData64 определена только для абстрактного класса –

Смежные вопросы