Core Dataスタックを正しく初期化しますか?





お気に入りのiOSアプリのいずれかが次の更新後に機能しなくなったことに気づいたことはありますか? 通常、その後、開発者は緊急のバグ修正をリリースします。 そして、これは常に最終的なプログラマーのコードのバグに関連付けられているわけではありません。時には、問題はもう少し深いところにあります。



このエラーは非常に頻繁に発生する(そして「深刻な」プロジェクトで発生するはずです)ことは私にはかなり奇妙に思えますが、何らかの理由で彼らはそれについて沈黙しています。

この記事では、iOSアプリケーションでCoreDataスタックを初期化する際の標準エラーについて説明します。



CoreDataフレームワークは、Cocoa開発者の手にある強力なツールであり、ほぼ無料の永続性、データ変更の容易さ、記録、バージョンサポート、モデルからモデルへの移行-私たちのプロジェクトで頻繁に必要なものです。 誰かがそれを読み取り専用モードで使用し、誰かがかなり節約してそのような小さな選択で動作しますが、誰かがそれを最大限に使用します。



エラーが発生するためには、3つの理由を収集する必要があります:データベースサイズが大きい、メインスレッドのCoreDataスタックの初期化、プログラムの新しいバージョンのデータベーススキーマの変更。 それらすべてを開発者としてどれだけ簡単に組み立てられるかを見てみましょう。





理由#1。 大きなデータベースファイルサイズ


「完全に」使用すると、ベースのサイズが人為的に無制限になり、ギガバイトを簡単に占有することがよくあります。



後者の例については、長時間行く必要はありません。 インターネットでは、写真をデータベースに保存できるかどうか疑問に思っています(ちなみに、この記事ではCoreDataとデータベースはほぼ同義語になります)。 Stackoverflowのオーディエンスの承認を得た非常に人気のある回答は、最大1メガバイトの写真までデータベースに安全に保存できることを示唆しています。 たとえば、ここにstackoverflow.com/questions/2573072/coredata-store-images-to-db-or-not



答えは次のようになります。



関連するデータと同じテーブルに100kb未満のストア

不必要なロードを回避するために、リレーションシップを介して接続された個別のテーブルに1 MB未満のストア

>ディスク上の1 MBのストアとコアデータ内での参照



または、アプリケーションに過去3年間のアクティブなユーザー通信(メッセンジャー、メールクライアントなど)を保存できます。

大量になった理由がわかりました。



理由番号2。 メインスレッドでの初期化


まあ、本当に疑問がありますか? メインプログラムフローでCoreDataスタック全体を初期化する可能性が高いのは、新規参入者の約100%と開発者の正確に70%です。



理由番号3。 新しいデータスキーマに移行する必要がある


通常、データベーススキーマ(モデル)を変更するときに、適切なルールを設定すると、CoreDataは古いデータベースから新しいデータベースにデータを転送します。 最も単純ないわゆる 軽量な移行は簡単です。ストレージをNSPersistentStoreCoordinatorに接続するときにオプション辞書を渡す必要があります。



NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:optionsDictionary error:&error];
      
      







転送が軽量移行のフレームワークに適合しない場合、開発者はカスタムを実現しますが、理由3の本質は変わりません。



収集された理由



理由はまとめられています。 それらを組み立てるのは非常に簡単ですよね? さて、これらの理由は、プロジェクトの形成の夜明けに初期化コードを挿入し、iTunesで次のようなものを見るまで安全に忘れていた多くの開発者によって単に収集されたものです。



, !



203 203









何が起こっているの?



これらすべての理由から、単純な結論に導かれると思います。 そして彼は忠実です! 単に移行データを新しいバージョンのデータベースにコピーするだけでも時間がかかり、データベースファイルの時間が長くなればなるほど、時間がかかります。 また、単純なコピーについても話します。たとえば、フィールドのインデックスを再作成する必要がある場合はどうでしょうか。



ボトルネックについてはすでに述べました-これは、永続ストレージとNSPersistentStoreCoordinatorオブジェクトの接続です。 これは、理由をまとめると問題が発生する場所です。 また、アプリケーションが30秒間応答しない場合、システムはそれを閉じます。



解決策



幸いなことに、NSPersistentStoreCoordinatorを作成して、別のスレッドでストレージを接続できます。 また、データの初期化時に、たとえば「データの更新」という碑文が表示されたウィンドウを表示するのは良い口調です。



コード内での表示方法は次のとおりです(ソリューションが完璧であると主張していないことをすぐに言います。誰かがもっとよく考えれば、コメントを書きます)。



 //     GUI    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.launchOptions = launchOptions; [self performSelectorInBackground:@selector(initCoreData) withObject:nil]; [NSThread sleepForTimeInterval:0.2]; // ,       ,    .        [self initialDisplayGUI]; return YES; } - (void)initialDisplayGUI { if (self.dataIsReady) { [self diplayAllGUIStuff]; } else { self.dataPrepareController = [[MigrationProgressViewController alloc] init]; [dataPrepareController setDoneTarget:self withAction:@selector(diplayAllGUIStuff)]; dataPrepareController.view.frame = window.frame; [window addSubview:dataPrepareController.view]; [window makeKeyAndVisible]; } } - (void)initCoreData { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; if (self.persistentStoreCoordinator) { NSLog(@"Storage was added"); } self.dataIsReady = YES; [pool release]; } - (void)setDataIsReady:(BOOL)dataIsReady { if (_dataIsReady != dataIsReady) { _dataIsReady = dataIsReady; [self performSelectorOnMainThread:@selector(diplayAllGUIStuff) withObject:nil waitUntilDone:NO]; } }
      
      







-diplayAllGUIStuff-持っていたコードを含むメソッド-(BOOL)アプリケーション:didFinishLaunchingWithOptions:



MigrationProgressViewControllerは、たとえば、残り時間のインジケーターを表示したり、少なくともプロセスがハングしていないことを示すために必要です。 その唯一のタスクは、ユーザーを安心させることです。 ユーザーは、ぶら下がりスクリーンセーバーよりも「裸の」UIActivityIndi​​catorViewを見る方が快適であり、さらにクラッシュしたアプリケーションが手元にあります。



おそらくそれだけです。 このような偶然の一致を避け、コード、特にXcodeが挿入したコードをよく確認してください。

画像







All Articles