0

私の状況はこの質問に似ています。私は次のコードで軽量の移行を使用していますが、Appleドキュメントや他のSOスレッドからはかなりバニラです。CoreDataスタックを初期化するときにアプリの起動時に実行されます。

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
    nil];

NSError *error = nil;

NSString *storeType = nil;
if (USE_SQLITE) { // app configuration
    storeType = NSSQLiteStoreType;
} else {
    storeType = NSBinaryStoreType;
}

persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

// the following line sometimes crashes on app startup
if (![persistentStoreCoordinator addPersistentStoreWithType:storeType configuration:nil URL:[self persistentStoreURL] options:options error:&error]) {
    // handle the error
}

一部のユーザー、特に低速のデバイスでは、示された行のログでクラッシュが確認されています。

修正は、これを手動のマッピングと移行に切り替えることであることを理解しています。それを行うためのレシピは何ですか?私にとっての長い道のりは、すべてのAppleドキュメントを読むことですが、特にスキーマ移行のための良い例とチュートリアルがあったことを思い出しません。

4

1 に答える 1

3

手動で移行する方法については良い例がありますが、基本的な手順は次のとおりです。

  • マッピング モデルを作成する
  • そのマッピング モデルをプロジェクトに含めます
  • 自動移行をオフにする

しかし、クラッシュは何ですか?時間がかかりすぎてOSに殺されていますか?手動の移行ではそれが解決しないためです。

どのタイプのバッキング ストアを使用していますか? バイナリを使用している場合、移行ではデータベース全体の 2 つのコピーがメモリに存在するため、メモリが不足する可能性があります。

OPコメントから更新

私はこれが SQLite でも起こるのを見たと思うので、メモリ以上のものがあるかもしれませんが、それは有効なポイントです。はい、特に 1G デバイスでは、時間がかかりすぎるために OS によって強制終了されます。手動移行は、「タイムアウト制約のあるアプリの起動時に移行する」から、時間の制約がないものに移行する方法でもあり、おそらくバックグラウンド スレッドなどで行うと考えました。?

データのソースを変更しているため、バックグラウンド スレッドで移行を行う方法はありません。移行の開始に時間がかかりすぎる場合、推奨される解決策は次のとおりです。

  • Core Data に触れることなく、実行ループの-applicationDidFinishLaunching:サイクルを完了させます。これでクラッシュが止まります
  • 実行ループを介して次の反復で移行を開始し (おそらく、何らかの進行状況インジケーターをユーザーに表示する必要があります)、移行を完了します。

バイナリ ストアを使用している場合は、メモリの問題が発生する可能性がありますが、起動時のクラッシュは解決されます。クラッシュは、「ロックアップしたと思います」とOSが言っていることです。完全-applicationDidFinishLaunching:にすることで、ロックしていないことを OS に伝えます。

于 2010-04-16T16:37:01.817 に答える