2

Apple のドキュメントを見ると、AppDelegate から Core Data 初期化コードを削除することを推奨しているようです。彼らのアプローチは以下のとおりです。

わからないのは以下

  1. ドキュメントの下の文。アプリ デリゲートへのコールバックはどのように行われますか? 以下のコード スニペットには表示されません。それは彼らが私たちに追加したいものですか?

完了ブロックを使用して別のコントローラー オブジェクトを初期化することにより、Core Data スタックをアプリケーション デリゲートの外に移動しましたが、アプリケーション デリゲートへのコールバックを引き続き許可して、ユーザー インターフェイスがいつデータの要求を開始するかを認識できるようにします。

  1. AppDelegate は DataController の init を呼び出し、これが次に initializeCoreData を呼び出します。ただし、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]);
    });
}
4

2 に答える 2

0

YESメソッドからのリターンapplicationDidFinishLaunchingWithOptionsが鍵です。

コア データ スタックの初期化は、メソッドが返される前、またはビュー コントローラーが初期化される前に行われます。Core データ スタックは、アプリが実際に起動されていることが通知されるとすぐに初期化されます。初期化プロセス全体の後でのみ、メソッドは を返しますYES。その後、ストーリーボードが最初のコントローラーとともにロードされ、次に最初のコントローラーviewDidLoadがロードされます。

そのため、ある意味では、最初のコントローラーが画面に表示されるずっと前に、Core データ スタックが読み込まれます。

これが理解に役立つことを願っています。

于 2016-09-18T17:00:15.460 に答える