Когда мы создаем новый проект в XCode с выбранной опцией Core Data, он генерирует новый проект, определяющий стек основных данных в AppDelegate.swift:
class AppDelegate: UIResponder, UIApplicationDelegate {
// ...
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "CoreDataTest")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
Для меня, чтобы легко получить доступ к persistentContainer
,Я также добавил этот фрагмент кода:
static var persistentContainer: NSPersistentContainer {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { fatalError("Could not convert delegate to AppDelegate") }
return appDelegate.persistentContainer
}
Так что я могу назвать его так:
let container = AppDelegate.persistentContainer
Проблема возникает, когда я пытаюсь получить к нему доступ из фонового потока.Например, у меня есть фрагмент кода, который работает в фоновом режиме и получает некоторые данные из веб-службы.Когда он получает данные, я сохраняю их, используя:
static func loadData(_ id: String) {
fetchDataOnBackground(id: id) { (error, response) in
if let error = error {
// handle...
return
}
guard let data = response?.data else { return }
let container = AppDelegate.persistentContainer // Here
container.performBackgroundTask({ context in
// save data...
})
}
}
Когда я пытаюсь получить постоянный контейнер, он генерирует на консоли:
Main Thread Checker: UI API called on a background thread: -[UIApplication delegate]
Для этого неслучиться больше, я изменил свой persistentContainer
с lazy var
на static
на AppDelegate
:
static var persistentContainer: NSPersistentContainer = {
// same code as before...
}()
И ошибка больше не происходит.
Но ямне интересно, если это может иметь какие-либо побочные эффекты, о которых я не знаю.Я имею в виду, у меня все равно будет только один persistentContainer
, потому что есть только один экземпляр AppDelegate
, верно?Таким образом, я могу изменить его на статический, как я сделал, и получить доступ к нему с помощью AppDelegate.persistentContainer
в других частях моего приложения без каких-либо проблем?
Или есть другой рекомендуемый шаблон для обработки persistentContainer
создания и использования?