如何重置 CoreData 应用程序
Posted
技术标签:
【中文标题】如何重置 CoreData 应用程序【英文标题】:How to reset CoreData Application 【发布时间】:2013-09-05 12:38:18 【问题描述】:我正在尝试重置使用 Core Data 的应用程序,为此,我编写了以下代码
- (void) resetApplicationModel
// NSError *error;
NSError *error;
// retrieve the store URL
NSURL * storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"abc.sqlite"];
// lock the current context
[self.managedObjectContext lock];
[self.managedObjectContext reset];//to drop pending changes
//delete the store from the current managedObjectContext
if ([[self.managedObjectContext persistentStoreCoordinator] removePersistentStore:[[[self.managedObjectContext persistentStoreCoordinator] persistentStores] lastObject] error:&error])
// remove the file containing the data
if([[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error])
//recreate the store like in the appDelegate method
if([[self.managedObjectContext persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error] == nil)
NSLog( @"could not create new persistent store at %@ - %@", [storeURL absoluteString], [error localizedDescription]);
else
NSLog( @"could not remove the store URL at %@ - %@", [storeURL absoluteString], [error localizedDescription]);
else
NSLog( @"could not remove persistent store - %@", [error localizedDescription]);
[self.managedObjectContext unlock];
__managedObjectContext = nil;
[self managedObjectContext];
_rootViewController.controller = nil;//Make NSFetchResultsController nil;
此代码在 ios 6.1 模拟器上运行良好,没有问题,但是当我在运行 iOS 6.1.3 的 iphone 4 上检查此代码时,持久性文件没有被删除,我收到错误提示
“无法删除文件中的商店 URL://localhost/var/mobile/Applications/147E198E-FAB9-46EA-BE4B-4411AFA013FB/Documents/abc.sqlite - 操作无法完成。 (Cocoa 错误 4.)"
但是所有数据都被删除了,现在当我尝试在 coreData 中添加新数据时,我收到一个错误提示
" 由于未捕获的异常 'NSInternalInconsistencyException' 导致应用程序终止,原因:'此 NSPersistentStoreCoordinator 没有持久存储。它无法执行保存操作。'"
请帮帮我
问候 兰吉特
【问题讨论】:
您只是想删除护理数据对象中的所有数据吗?如果是这样,您不需要删除文件,您可以简单地删除所有对象,从而为您提供干净的核心数据堆栈。我在 NSManagedObjectContext 上写了一个类别来实现这一点(见我的回答) 无需锁定/解锁上下文,这已经是线程安全的,您可以通过锁定存储协调器来达到相同的效果。 【参考方案1】:在 NSManagedObjectContext 上创建一个类别然后实现:
- (BOOL)deleteAllObjectsForEntityName:(NSString *)entity withError:(NSError *__autoreleasing *)error
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:entity inManagedObjectContext:self]];
[request setIncludesPropertyValues:NO];
NSArray *allObjects = [self executeFetchRequest:request error:error];
if (![self save:error])
return NO;
for (NSManagedObject *object in allObjects)
[self deleteObject:object];
return YES;
然后使用它只需这样做:
- (void)deleteAllObjectsForEntityName:(NSString *) entity
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
if (![managedObjectContext deleteAllObjectsForEntityName:entity withError:&error])
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
输入您的实体名称,它将全部删除:-)
【讨论】:
感谢您的代码。我并不是说你做错了,但我一直想知道为什么人们为了做简单的任务而在层之上构建层,在这种情况下删除。 这是一种方便的方法,一旦完成,我可以将核心数据的类别和我的单例迁移到任何项目中,并且无需更改一行代码即可正常工作。写完我就可以忘记了。当涉及到重构时,将使您的逻辑代码更清晰、更易于阅读和更易于管理。 加上我最多花了 20 分钟来写。您尝试调试问题多长时间了 :-) 20 分钟该死的快 :-) 我想再次指出我并不是说这是错误的,相反我很欣赏你的工作。我只是觉得很奇怪,因为删除所有对象是一项非常了不起的任务,不能仅仅委托给上下文,我怀疑任何应用程序都需要它。但是没有对错之分。如果你这样做,你肯定有一个理由,所以你可能是对的。所以,继续做好工作:-) @CW0007007,删除所有对象是一项昂贵的工作,因此建议删除持久存储以上是关于如何重置 CoreData 应用程序的主要内容,如果未能解决你的问题,请参考以下文章
CoreData崩溃“无法在绑定{}中获取'批处理'的值。”重置NSManagedObjectContext时