2

我的应用程序将当前用户的大量数据存储在 Core Data 持久存储中。如果用户注销,我想删除所有这些数据并重新开始。

现在,我的代码如下所示:

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

对于我们正在进行的一个项目,我担心这个,所以我做了一个测试,但我不能让它显示你看到的行为。这一切都在 iOS 5.1 的模拟器中。

我刚刚在 Apple 的默认核心数据模板中尝试了以下代码,其模型具有单个实体“Entity”和一个名为“name”的字符串属性。代码插入一个实体,保存上下文,删除存储,删除存储文件,然后重新添加存储。正如预期的那样,对象在移除存储之前存在,之后不存在。(我也尝试添加 managedObject 锁定/重置/解锁,结果相同。)

所以,肯定有其他事情发生。您可以尝试制作这样的简化测试用例吗?

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 回答