Ответ
Нет. Core Data не является потокобезопасной по умолчанию. Объекты NSManagedObjectContext и NSManagedObject должны использоваться только в том потоке (очереди), в котором они были созданы.
Основные правила потокобезопасности:
- Каждый контекст (
NSManagedObjectContext) привязан к конкретной очереди. - Управляемые объекты (
NSManagedObject) нельзя напрямую передавать между контекстами из разных потоков.
Безопасная работа с контекстами:
Используйте методы perform или performAndWait для выполнения операций в правильной очереди.
// Создание приватного контекста для фоновой работы
let privateContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
privateContext.parent = mainContext
privateContext.perform {
// Все операции с контекстом внутри этого блока
let newItem = Item(context: privateContext)
newItem.name = "Sample"
do {
try privateContext.save() // Сохраняем в приватный контекст
// Для сохранения в persistent store координатору может потребоваться
// сохранение родительского (main) контекста.
} catch {
print("Save error: (error)")
}
// Обновление UI должно происходить на главном потоке
DispatchQueue.main.async {
// Обновить интерфейс
}
}
Рекомендуемые практики для многопоточности:
- Используйте соответствующий тип контекста:
.mainQueueConcurrencyTypeдля UI,.privateQueueConcurrencyTypeдля фоновых задач. - Для передачи изменений между контекстами используйте родительско-дочерние иерархии или слияние через уведомления (
NSManagedObjectContextDidSave). - Для передачи идентификаторов объектов между очередями используйте
NSManagedObjectID.