Я не испытал эту ошибку на iOS9. Однако вы должны посмотреть свои журналы, чтобы узнать, какие у вас ошибки. Возможно ли, что вы столкнулись со своей «Ошибка добавления постоянного хранилища» при создании PSC?
У вашего метода возникла проблема в том, что если вы когда-нибудь столкнетесь с этой ошибкой, последующие вызовы возвратят PSC, который не будет ни нул, ни правильно настроен.
Причина в том, что вы назначили свой _persistentStoreCoordinator
, прежде чем он будет успешно настроен. Таким образом, если есть какая-либо ошибка, вы возвращаете нуль, но при следующем вызове этого метода вы вернете PSC без магазинов.
В любом случае вы должны изменить этот метод, чтобы вы только возвращали либо ноль, либо полностью работоспособный PSC.
Я бы изменил этот метод на что-то подобное. Примечание, однако, что я никогда бы не построил такой базовый стек данных, как этот. Однако, по крайней мере, следующий код исправит вашу ошибку, если вы можете вернуть частично созданный PSC.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSURL *storeURL = [[delegate applicationDocumentsDirectory]
URLByAppendingPathComponent:@"database.sqlite"];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:self.managedObjectModel];
NSError *error = nil;
if (![psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:@{NSMigratePersistentStoresAutomaticallyOption:@YES,
NSInferMappingModelAutomaticallyOption:@YES}
error:&error]) {
NSLog(@"Error adding persistent store. %@, %@", error, error.userInfo);
} else {
_persistentStoreCoordinator = psc;
}
return _persistentStoreCoordinator;
}
EDIT
Не хватает места в комментариях, чтобы ответить на ваш вопрос, так что я положил его здесь.
@JodyHagins - также, вы говорите, что вы не будете строить свой стек, как это, вы можете, дайте мне знать, что случилось с моим стеком? - AWillian
Я сделал это замечание, потому что код размещен устрашающе похож на шаблон ядра данных в Xcode по умолчанию. Вы вызываете приложение-делегат для получения каталога, указывая, что это не в приложении-делетете, что хорошо.
Однако этот метод указывает на то, что вы обращаетесь к нему с ленивым «где угодно», что указывает на то, что ваш стек не построен так, как я бы создал стек (тем более, что вы также включаете параметры миграции).
Я не хотел подразумевать, что то, что вы делали, было неправильным, само по себе, это не то, как я это сделаю.
Теперь я буду первым, чтобы сказать, что то, что я делаю, это то, что я делаю ... и я не говорю, что это правильный путь ... только по-моему. На самом деле, я не видел, чтобы кто-то другой действительно делал то, что я делаю (я действительно подклассифицировал NSManagedObjectContext, хотя я не помню предупреждения и держался подальше от пронзительных бит). Это само по себе может указывать на то, что то, что я делаю, может быть неправильным для вас или кого-либо еще. Но я нашел, что это правильно для меня, и довольно сложные приложения, которые мне пришлось реализовать.
Итак, как мне построить стек?
Ну, это достойно чего-то гораздо более глубокого, чем ответ SO, поэтому я буду краток. Это также зависит от типа стека - родителя/ребенка, братьев и сестер с тем же PSC, двоюродных братьев с разными PSC, но в тех же магазинах.
Во-первых, я не предоставляю отдельный доступ к модели и координатору. Вы можете легко получить доступ к ним из контекста, и обычно это приводит к большим проблемам, чем их ценность.
Вне испытаний и тривиальных примеров, я всегда создаю мой MOC асинхронно, что-то вроде этого ...
+ (void)createWithConcurrencyType:(NSManagedObjectContextConcurrencyType)concurrencyType
completion:(void(^)(NSManagedObjectContext *moc, NSError *error))completion;
MOM для создания и назначен ККП, ККП создается и присваивается MOC , Это происходит асинхронно, так что потенциально длительный процесс открытия и инициализации может выполняться в фоновом потоке. Обработчик завершения вызывается в пределах performBlock
, поэтому MOC можно использовать чисто. Это также предотвращает использование до того, как MOC будет полностью настроен и прочитан.
Даже если вызывается с использованием типа параллелизма основной очереди, вся работа выполняется в фоновом потоке, так что в основной поток вызывается только завершение.
Я также использую тот же шаблон при создании связанных MOC для импорта и временных целей.
Я бы честно добавил 'abort()' после 'NSLog', чтобы убедиться, что проблема поймана как 99.999% времени, когда приложение бесполезно, если исходный код не инициализирован правильно. –
@ MarcusS.Zarra - Согласовано. –
Спасибо, что поймали это, похоже, что это наиболее вероятная причина. Хотя интересно, что это началось только на iOS9, и меня также интересует, что означает [NSPersistentStoreCoordinator _coordinator_you_never_successfully_opened_the_database_device_locked:]. – AWillian