2012-07-31 86 views
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]; 

但无论我做什么,我下次执行读取请求我得到的所有旧数据了。我已经验证过实际的文件正在从文件系统中删除,所以显然这些数据来自某处的内存。我已经尝试了上面的代码,我已经尝试将托管对象上下文重置为零,并从头开始,但是在我终止应用程序并重新运行它之前,没有任何更改会发生。

编辑:其实,甚至没有终止应用程序做任何事情。我看到sqlite文件从NSFileManager行之后的文件夹中消失,然后在添加新持久性存储的行中重新创建旧文件的确切副本。

编辑:好的,我打开了核心数据调试。只要我打电话removePersistentStore:,我看到“与sqlite数据库断开连接”。接下来的行addPersistentStoreWithType:,我看到大量的INSERT声明,我猜是神奇地从内存中恢复数据库的内容?我可以得到它...不是那样做的吗?

编辑︰好吧,现在我已经通过循环我的管理对象手动删除数据存储的内容。这个工作,不知何故。幸运的是,对于这个项目,用户只有几百个对象,所以这不是非常耗时,但我仍然希望我明白发生了什么......

+0

我假设你没有在上面的代码中出现任何错误?您也可以打开核心数据调试以查看正在执行的SQL。 – 2012-07-31 00:18:15

+0

谢谢,我不知道有一个核心数据调试选项。我编辑了我的问题。 – 2012-07-31 00:28:44

回答

0

撕下整个堆栈,然后删除文件。如果您使用的是UIManagedDocument,那么您有一个文件包。确保关闭文档,然后删除整个文件包。

+0

我试着按照这个顺序来做,但它没有区别。我没有使用UIManagedDocument。 – 2012-07-31 00:39:20

+0

你现在试试哪些代码? – 2012-07-31 01:01:49

+0

我调用了'removePersistentStore:',然后将持久性存储,持久性存储协调器,托管对象模型和托管对象上下文设置为'然后我以不同的用户身份重新登录,但仍可以看到以前用户的所有数据。我逐字逐行地逐行浏览所有内容,并在Finder窗口中看到文件被删除:/ – 2012-07-31 13:11:08

0

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

我刚刚在Apple的默认核心数据模板中使用带有名为“name”的字符串属性的单个实体“Entity”的模型尝试了以下代码。代码插入一个实体,保存上下文,删除存储,删除存储文件,然后重新添加存储。如预期的那样,物品在移除商店之前存在并且在之后不存在。 (我也尝试添加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]); 
+0

发生同样的事情。当我在后台进行一些提取操作时,我有一个第二个托管对象上下文,但我最终认为这不值得。该代码甚至不在我的项目中了。 – 2012-07-31 13:08:47

+0

@AnshuChimala我已经添加了一些注释;基本上,我无法重现你所看到的,所以我怀疑还有其他事情正在发生。 – 2012-07-31 14:12:02

+0

你可能会尝试的另一件事是在sqlite函数上放一个断点,并查看哪些代码导致你的行被插入。如果您有一个插入的堆栈跟踪,您可以发布它。 – 2012-07-31 14:13:18