2

私のアプリは、現在のユーザーの多くのデータをCoreData永続ストアに保存します。ユーザーがログアウトした場合、このデータをすべて削除して最初からやり直したいと思います。

現在、私のコードは次のようになっています。

NSError *error;
[_managedObjectContext lock];
[_managedObjectContext reset];
[_persistentStoreCoordinator removePersistentStore:_persistentStore error:&error];
[[NSFileManager defaultManager] removeItemAtURL:[_persistentStore URL] error:&error];
    // error handling here
_persistentStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self _storeURL] options:nil error:&error];
[_managedObjectContext unlock];

しかし、何をしても、次にフェッチリクエストを実行すると、すべての古いデータが返されます。実際のファイルがファイルシステムから削除されていることを確認したので、このデータはどこかのメモリから取得されているようです。上記のコードを試し、管理対象オブジェクトのコンテキストをnilにリセットして最初からやり直そうとしましたが、アプリを終了して再実行するまで、変更は行われていないようです。

編集:実際には、アプリを終了することさえ何もしません。行の後にあるフォルダーからsqliteファイルが消えNSFileManager、新しい永続ストアを追加した行に、古いストアの正確なコピーが再作成されます。

編集:さて、私はコアデータのデバッグをオンにしました。電話をかけるとすぐにremovePersistentStore:「sqliteデータベースから切断されました」と表示されます。次の行、、データベースの内容をメモリから魔法のように復元していると思われる大量addPersistentStoreWithType:INSERTステートメントが表示されますか?私はそれを得ることができます...それをしませんか?

編集:まあ、今のところ、管理対象オブジェクトをループしてデータストアのコンテンツを手動で削除するだけです。これはどういうわけか機能します。このプロジェクトにとって幸いなことに、ユーザーは数百のオブジェクトしか持っていないので、それほど時間はかかりませんが、何が起こっているのかを理解したいと思います...

4

2 に答える 2

0

スタック全体を破棄してから、ファイルを削除します。UIManagedDocument を使用している場合は、ファイル パッケージがあります。ドキュメントを閉じてから、ファイル パッケージ全体を削除してください。

于 2012-07-31T00:35:26.220 に答える
0

I was worried about this for a project we're working on, so I've made a test, but I can't make it show the behaviour you're seeing. This is all in the simulator with iOS 5.1.

I just tried the following code in Apple's default core data template with a model with a single entity "Entity" with a string property called "name". The code inserts an entity, saves the context, removes the store, deletes the store file and then re-adds the store. The objects are present before removing the store and absent afterwards, as expected. (I've also tried adding the managedObject lock/reset/unlock, with the same results.)

So, there must be something else going on. Can you try to make a reduced test-case like this?

NSManagedObject *object = [[NSManagedObject alloc] initWithEntity:[NSEntityDescription entityForName:@"Entity"
                                                                              inManagedObjectContext:self.managedObjectContext]
                                   insertIntoManagedObjectContext:self.managedObjectContext];
[object setValue:@"hi" forKey:@"name"];
NSError *error;
if (![self.managedObjectContext save:&error]) {
    NSLog(@"error: %@",error);
}

NSFetchRequest *fetch = [[NSFetchRequest alloc] initWithEntityName:@"Entity"];
[fetch setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]];

NSLog(@"before: %@", [self.managedObjectContext executeFetchRequest:fetch error:nil]);


if (![self.persistentStoreCoordinator removePersistentStore:[[self.persistentStoreCoordinator persistentStores] lastObject]
                                                      error:&error]) {
    NSLog(@"error: %@", error);
}

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataTest.sqlite"];

if (![[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error]) {
    NSLog(@"error: %@", error);
}

if (![self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                              configuration:nil
                                                        URL:storeURL
                                                    options:nil
                                                           error:&error]) {
    NSLog(@"error: %@", error);
}

NSLog(@"after: %@", [self.managedObjectContext executeFetchRequest:fetch error:nil]);
于 2012-07-31T01:13:35.247 に答える