Bur*_*urt 11 sqlite iphone core-data
在我的应用程序中,我有时需要重建和重新填充数据库文件.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';
Run Code Online (Sandbox Code Playgroud)
我无法以任何方式找到原因.它表示两个不同的问题 - 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]);
Run Code Online (Sandbox Code Playgroud)
在此代码被执行后,DB文件存在但是为空.当执行第一次查询(以及所有后续查询)时,它会给我上面的错误并且文件消失.
有人知道它有什么问题吗?
非常感谢指出我正确的方法!
Mar*_*rra 18
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;
}
Run Code Online (Sandbox Code Playgroud)