1

С основными данными есть постоянный танец вокруг проблем безопасности нитей. Выполнение выборок на одном NSManagedObjectContext в двух разных потоках гарантирует тупик. Руководство Apple по программированию ядра предлагает использовать ограничение потока, но не предоставляет шаблон, с помощью которого вы можете выполнить это. У меня есть быстрый и грязный раствор ниже:NSManagedObjectContext: Является ли это хорошим шаблоном ограничения потока?

- (NSManagedObjectContext *) managedObjectContext 
{ 
    NSManagedObjectContext *moc = objc_getAssociatedObject([NSThread currentThread], _cmd); 

    if (!moc && self.persistentStoreCoordinator) 
    { 
     moc = [[NSManagedObjectContext alloc] init]; 
     moc.mergePolicy = NSOverwriteMergePolicy; 
     moc.persistentStoreCoordinator = self.persistentStoreCoordinator; 
     objc_setAssociatedObject([NSThread currentThread], _cmd, moc, OBJC_ASSOCIATION_RETAIN); 
    } 

    return moc; 
} 

Этот метод будет отображаться в собственном классе, который управляет стек данных в моем приложении. Он связывает MOC с текущей нитью. Это кажется правдоподобным решением для меня, но оно также кажется быстрым и свободным.

Что я должен беспокоиться о попытке решения такого рода?

+1

Посмотрите на [Grand Central Dispatach] (http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html). Я нахожу его более чистым, чем непосредственное взаимодействие с потоками, и у меня были успешные завершающие вызовы на мой MOC в отдельной очереди отправки. Основываясь на том, что вы показали, я не думаю, что необходимо использовать такие функции времени исполнения. –

+0

Также, кстати, у NSThread синглетонов есть 'threadDictionary', которые вы можете использовать для связывания объектов с потоком. Это безопаснее, чем возиться с функциями времени выполнения :) –

ответ

1

Вы должны идти наоборот: Используйте

[NSManagedObjectContext alloc] initWithConcurrencyType:concurrencyType]] 

создать контекст

  • NSMainQueueConcurrencyType - если вам нужен контекст, связанный с контроллерами и объектами пользовательского интерфейса, которые необходимы для использования только на основной нити, или
  • NSPrivateQueueConcurrencyType - для контекста, который выполняется в частной очереди фона.

Использование performBlock или performBlockAndWait для всех операций по контексту, это гарантирует, что операции выполняются на очереди, заданной для контекста.

См. Concurrency Support for Managed Object Contexts в «Замечаниях по выпуску основных данных для OS X v10.7 и iOS 5.0» для получения дополнительной информации.