В документации Apple я вижу, что они рекомендуют удалить код инициализации Core Data из AppDelegate. Их подход ниже.Инициализация основных данных
То, что я не понимаю, являются следующие
- Предложение ниже в документации. Как происходит обратный вызов делегата приложения? Я не вижу этого в фрагментах кода ниже. Это то, что они хотят, чтобы мы добавили.
При инициализации отдельного объекта контроллера с блоком завершения, вы переместились стек основные данные из делегата приложения, но вы все еще допускаете обратный вызов для приложения делегата так, что пользовательский интерфейс может знать когда начинать запрашивать данные.
- AppDelegate вызывает init DataController, и это, в свою очередь, вызывает инициализациюCoreData. Но initializeCoreData устанавливает постоянный координатор хранилища в фоновом потоке. Это означает, что если мы перейдем к первому представлению приложения, а его контроллер представления запросит данные из основных данных, все еще не настроено. Не будет ли это проблемой? Означает ли это, что они хотят, чтобы мы показывали другой экран запуска. & регистр для обратного вызова, который сообщает нам, что инициализация CoreData выполняется до перехода на фактический вид приложения.
AppDelegate код в документации
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self setDataController:[[DataController alloc] init];
// Basic User Interface initialization
return YES;
}
DataController код в документации
@interface MyDataController : NSObject
@property (strong) NSManagedObjectContext *managedObjectContext;
-(void)initializeCoreData;
@end
@implementation MyDataController
-(id)init {
self = [super init];
if (!self) return nil;
[self initializeCoreData];
return self;
}
- (void)initializeCoreData {
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"DataModel" withExtension:@"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSAssert(mom != nil, @"Error initializing Managed Object Model");
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc setPersistentStoreCoordinator:psc];
[self setManagedObjectContext:moc];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *documentsURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [documentsURL URLByAppendingPathComponent:@"DataModel.sqlite"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
NSError *error = nil;
NSPersistentStoreCoordinator *psc = [[self managedObjectContext] persistentStoreCoordinator];
NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];
NSAssert(store != nil, @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]);
});
}
Я не согласен. У 'initializeCoreData' есть' dispatch_async' в конце. Таким образом, он будет возвращен до выполнения этого блока кода. Следовательно, нет гарантии, что блок внутри 'disaptch_async'' initializeCoreData' завершился, когда [DataController init] вернулся. –
Вы правы. Вам нужно будет сообщить своему пользовательскому интерфейсу, что CoreData готов к использованию. Один из способов сделать это - через NSNotifications, или другой способ - иметь «свойство» (например, Bool?), Которое получает значение true, чтобы наблюдатель ключевых значений мог срабатывать, когда пользовательский интерфейс может полагаться на CoreData. –
@SmartHome - обсуждение [iCloud-core-data] (https://developer.apple.com/library/content/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/UsingSQLiteStoragewithiCloud/UsingSQLiteStoragewithiCloud.html#//apple_ref/doc/uid/ TP40013491-CH3-SW1) рассказывает об уведомлениях, которые даются, когда хранилище temp заменяется «реальным» хранилищем. Я подозреваю, что они предлагают код, который упрощает переход приложения с локальным хранилищем в хранилище облаков. Но, как ни странно, они не показывают * как * обрабатывать PSCDidChange и как повторно отображать пользовательский интерфейс. Документ iCloud предлагает вам просто «перезагрузить» MOC. – stevesliva