Многопоточное использование основных данных (NSOperationQueue и NSManagedObjectContext)
В документации Apple Core Data для Concurrency с основными данными они перечисляют предпочтительный метод безопасности потоков, поскольку используют отдельный NSManagedObjectContext для потока, с общим NSPsistentStoreCoordinator.
Если у меня есть ряд NSOperations, запущенных один за другим в NSOperationQueue, будут ли большие накладные расходы, создающие контекст с каждой задачей?
Если NSOperationQueue имеет максимальное количество одновременных операций 1, многие из моих операций будут использовать один и тот же поток. Могу ли я использовать словарь потоков для создания одного NSManagedObjectContext для потока? Если я это сделаю, у меня будут проблемы с очисткой моих контекстов позже?
Каков правильный способ использования Core Data в этом случае?
Ответы
Ответ 1
Правильный способ использования Core Data в этом случае - создать отдельный NSManagedObjectContext
для каждой операции или иметь единственный контекст, который вы заблокируете (через -[NSManagedObjectContext lock]
перед использованием и -[NSManagedObjectContext unlock]
после использования). Заблокированный подход может иметь смысл, если операции являются последовательными и нет других потоков, использующих контекст.
Какой подход к использованию является эмпирическим вопросом, который не может быть обеспечен без данных. Слишком много переменных имеют общее правило. Жесткие номера от тестирования производительности - единственный способ принять обоснованное решение.
Ответ 2
Операции, запущенные с использованием NSOperationQueue, с использованием максимального количества одновременных операций 1, не будут запускать все операции в одном потоке. Операции будут выполняться один за другим, но каждый раз будет создан новый поток.
Таким образом, создание объектов в словаре потоков будет малопривлекательным.
Ответ 3
Пока этот вопрос устарел, он фактически находится в верхней части результатов поиска Google в разделе "NSMangedObjectContext threading", поэтому я просто напишу новый ответ.
Новый "предпочтительный" метод - использовать initWithConcurrencyType: и сообщить MOC, является ли он основным потоком MOC или вторичным потоком moc. Затем вы можете использовать новые методы executeBlock: и executeBlockAndWait: на нем, и MOC позаботится о сериализации операций над его "родным" потоком.
Затем возникает вопрос, как вы разумно справляетесь с объединением данных между различными MOC, которые могут появиться вашим приложением, а также тысячами других деталей, которые делают жизнь "забавой" в качестве программиста.