在我的应用程序中,我有时需要重建和重新填充数据库文件.SQLite数据库由CoreData堆栈创建和管理.
我要做的是删除文件,然后只需重新创建persistentStoreCoordinator对象.
它在模拟器下工作,但在设备上没有,我收到这样的错误:
NSFilePath = "/var/mobile/Applications/936C6CC7-423A-46F4-ADC0-7184EAB0CADD/Documents/MYDB.sqlite"; NSUnderlyingException = I/O error for database at /var/mobile/Applications/936C6CC7-423A-46F4-ADC0-7184EAB0CADD/Documents/MYDB.sqlite. SQLite error code:1, 'table ZXXXX already exists';
我无法以任何方式找到原因.它表示两个不同的问题 - Cocoa错误256表示文件不存在或不可读.但是在创建persistenStoreCoordinator之后创建了文件IS,尽管它是空的,但是在执行一些查询之后它就消失了.
在这种情况下,表示尝试创建alredy现有表的第二条消息非常奇怪.
我很困惑,无法明白这里发生了什么.我的代码看起来像这样:
NSString *path = [[WLLocalService dataStorePath] relativePath]; NSError *error = nil; WLLOG(@"About to remove file %@", path); [[NSFileManager defaultManager] removeItemAtPath: path error: &error]; if (error != nil) { WLLOG(@"Error removing the DB: %@", error); } [self persistentStoreCoordinator]; WLLOG(@"Rebuild DB result %d", [[NSFileManager defaultManager] fileExistsAtPath: path]);
在此代码被执行后,DB文件存在但是为空.当执行第一次查询(以及所有后续查询)时,它会给我上面的错误并且文件消失.
有人知道它有什么问题吗?
非常感谢指出我正确的方法!
Core Data堆栈不喜欢你删除它下面的文件.如果您要删除文件,则应拆除堆栈,删除文件,然后重新构建堆栈.这将消除这个问题.
部分问题是堆栈保留了文件中数据的缓存.删除文件时,您无法清除该缓存,然后将Core Data置于未知且不稳定的状态.
您可以尝试NSPersistentStoreCoordinator
通过调用告诉您正在删除文件,-removePersistentStore:error:
然后通过调用添加新商店-addPersistentStoreWithType:configuration:URL:options:error:
.我目前在ZSync中这样做,它工作得很好.
我-resetApplicationModel
在我的app委托中使用以下方法,它对我来说很好.
您可能不需要kApplicationIsFirstTimeRunKey
用户默认值,但我使用它来测试是否使用调用的自定义方法使用默认设置填充Core Data存储,如果首次运行标志为-setupModelDefaults
,我也会调用-applicationDidFinishLaunching:
该方法YES
.
- (BOOL) resetApplicationModel { // ---------------------- // This method removes all traces of the Core Data store and then resets the application defaults // ---------------------- [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:kApplicationIsFirstTimeRunKey]; NSLog(@"Turned ON the first-time run flag..."); NSError *_error = nil; NSURL *_storeURL = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"MyAppSQLStore.sqlite"]]; NSPersistentStore *_store = [persistentStoreCoordinator persistentStoreForURL:_storeURL]; // // Remove the SQL store and the file associated with it // if ([persistentStoreCoordinator removePersistentStore:_store error:&_error]) { [[NSFileManager defaultManager] removeItemAtPath:_storeURL.path error:&_error]; } if (_error) { NSLog(@"Failed to remove persistent store: %@", [_error localizedDescription]); NSArray *_detailedErrors = [[_error userInfo] objectForKey:NSDetailedErrorsKey]; if (_detailedErrors != nil && [_detailedErrors count] > 0) { for (NSError *_detailedError in _detailedErrors) { NSLog(@" DetailedError: %@", [_detailedError userInfo]); } } else { NSLog(@" %@", [_error userInfo]); } return NO; } [persistentStoreCoordinator release], persistentStoreCoordinator = nil; [managedObjectContext release], managedObjectContext = nil; // // Rebuild the application's managed object context // [self managedObjectContext]; // // Repopulate Core Data defaults // [self setupModelDefaults]; return YES; }