コアデータを操作するアプリがあります。現時点では V1.5 を使用していますが、これらのバージョンでは、コア データベースにいくつかの変更を加えました。アプリがまだクラッシュしているという苦情がいくつか寄せられた後、実装する必要があることがわかりましたCore data lightweight
。問題は今、私は別のバージョンで何を変更したのかわかりません。
また、コア データの操作については、スタンフォード大学のビデオ チュートリアルに従いました。 こちらはレッスン13です。
このチュートリアルを見ると、XCODE が appdelegate で生成する標準コードを使用していないことがわかります。彼が何をしているのかを簡単に説明します。
管理ViewWillAppear
されたドキュメントがあるかどうかを確認します。ない場合は、作成します。
if (!self.genkDatabase) {
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:@"Default appGenk Database"];
// url is now "<Documents Directory>/Default Photo Database"
self.genkDatabase = [[UIManagedDocument alloc] initWithFileURL:url]; // setter will create this for us on disk
}
ドキュメントが設定されたら、UseDocument
関数を呼び出します
- (void)setGenkDatabase:(UIManagedDocument *)genkDatabase
{
if (_genkDatabase != genkDatabase) {
_genkDatabase = genkDatabase;
[self useDocument];
}
}
次に、useDocument でドキュメントの状態を確認し、データを取得してコア データベースに保存します。
- (void)useDocument
{
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.genkDatabase.fileURL path]]) {
// does not exist on disk, so create it
[self.genkDatabase saveToURL:self.genkDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
NSLog(@"no database created yet");
[self fetchNewsIntoDocument:self.genkDatabase];
[self setupFetchedResultsController];
}];
} else if (self.genkDatabase.documentState == UIDocumentStateClosed) {
// exists on disk, but we need to open it
NSLog(@"closed");
[self.genkDatabase openWithCompletionHandler:^(BOOL success) {
[self fetchNewsIntoDocument:self.genkDatabase];
[self setupFetchedResultsController];
}];
} else if (self.genkDatabase.documentState == UIDocumentStateNormal) {
// already open and ready to use
[self setupFetchedResultsController];
}
}
これは、データベースにデータをフェッチする方法です。
- (void)fetchNewsIntoDocument:(UIManagedDocument *)document
{
dispatch_queue_t fetchNews = dispatch_queue_create("news fetcher", NULL);
dispatch_async(fetchNews, ^{
NSArray *news = [GenkData getNews];
[document.managedObjectContext performBlock:^{
int newsId = 0;
for (NSDictionary *genkInfo in news) {
newsId++;
[News newsWithGenkInfo:genkInfo inManagedObjectContext:document.managedObjectContext withNewsId:newsId];
}
[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
}];
});
dispatch_release(fetchNews);
}
私はこれが多くのコードであることを知っていますが、この問題を何日も探しているので、良い答えを得たいと思っています. 軽量コア データの移行について聞く前は、コア データに関する appdelegate には何もありませんでした。軽量移行の調査の後、appdelegate に標準の core-dat コードを追加し、これもコードに追加しました。
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Default appGenk Database.sqlite"];
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = @{
NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES
};
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
たくさんのコードを書いた後、実際の問題にたどり着きました。最初のビルドをインストールした iPad でプロジェクトを実行すると、データがデータベースに挿入された後に次のエラーが表示されます。
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation.'
誰でもこの問題で私を助けてくれることを願っています。私は、IOS 開発者としての経験が長くないため、この問題を解決するのは困難です。
敬具