2014-11-10 5 views
3

У меня есть старый проект (начал на прошивке 7) с помощью этого простого кода:NSManagedObjectContext и executeBlock, изменения в iOS 8?

в AppDelegate Я создаю managedObjectContext:

- (NSManagedObjectContext *)managedObjectContext { 
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) 
    if (_managedObjectContext != nil) { 
     return _managedObjectContext; 
    } 

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
    if (!coordinator) { 
     return nil; 
    } 
    _managedObjectContext = [[NSManagedObjectContext alloc] init]; 
    [_managedObjectContext setPersistentStoreCoordinator:coordinator]; 
    return _managedObjectContext; 
} 

Затем я выполнить операцию обновления в контроллере представления:

[context performBlock:^{ 
     [context deleteObject:anObject]; 

     NSError *error = nil; 
     if (![context save:&error]) 
     { 
      NSLog(@"Error saving context"); 
     } 
    }]; 

Я уверен, что этот код работает правильно на прошивке 7.0, но падает на performBlock: вызова на прошивке 8 с этой ошибкой:

Can only use -performBlockAndWait: on an NSManagedObjectContext that was created with a queue.

я могу решить ошибку изменяя метод инициализации экземпляра NSManagedObjectContext как это:

_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 

Но я не понимаю, почему это поведение изменилось. В документации NSManagedObjectContext вы можете прочитать:

A consequence of this is that a context assumes the default owner is the thread or queue that allocated it—this is determined by the thread that calls its init method.

Итак, в моем первом примере, используя простой init вызов, владелец очереди контекста является основным потоком. Звонок performBlock: также был сделан на основной поток, поэтому я не понимаю, почему эта ошибка. Я что-то упустил или это ошибка в iOS 8?

ответ

1

Звонок -[NSManagedObjectContext init] является просто оберткой для -[NSManagedObjectContext initWithConcurrencyType:] с аргументом NSConfinementConcurrencyType. Это создает экземпляр NSManagedObjectContext, который использует устаревшую модель ограничения контентов - в которой не использует очередь. Контексты, созданные с использованием init или initWithConcurrencyType: с переданным значением NSConfinementConcurrencyType, несовместимы с методами очереди performBlock: или performBlockAndWait:.

Создайте свой контекст, используя -[NSManagedObjectContext initWithConcurrencyType:] и пройдите либо NSPrivateQueueConcurrencyType, либо NSMainQueueConcurrencyType, если необходимо. Контекст, созданный в результате , является, совместимым с performBlock: и performBlockAndWait:, и будет использовать модель ограничения очереди, которая была представлена ​​в iOS 5.

+0

Спасибо. Я думаю, что предложение, которое я цитировал в Apple Docs, вводит в заблуждение :-) – LombaX

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