由于NSSQLiteErrorDomain=1032,iOS核心数据保存上下文方法不成功
关于这个问题的一些背景,我试图包括我认为可能有助于理解上下文的相关内容 我目前正在添加一个链接库,该库使用核心数据保存一些用户信息,并添加一个功能,将实体添加到应用程序中已经存在的核心数据模型中。每个managedObjectContext在创建(验证)时都有自己的实例以及自己的PSC和MOM,它们都不与其他实体交互(因此看起来是独立的) 以下所有代码、错误和(我相信问题)都是应用程序的主要目标。(希望不是新添加的链接库。 saveContext方法是:由于NSSQLiteErrorDomain=1032,iOS核心数据保存上下文方法不成功,ios,objective-c,sqlite,core-data,concurrency,Ios,Objective C,Sqlite,Core Data,Concurrency,关于这个问题的一些背景,我试图包括我认为可能有助于理解上下文的相关内容 我目前正在添加一个链接库,该库使用核心数据保存一些用户信息,并添加一个功能,将实体添加到应用程序中已经存在的核心数据模型中。每个managedObjectContext在创建(验证)时都有自己的实例以及自己的PSC和MOM,它们都不与其他实体交互(因此看起来是独立的) 以下所有代码、错误和(我相信问题)都是应用程序的主要目标。(希望不是新添加的链接库。 saveContext方法是: - (void)saveContext
- (void)saveContext {
dispatch_async(dispatch_get_main_queue(), ^{
NSError *error = nil;
// Register
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myManagedObjectContextDidSaveNotificationHandler:) name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];
if (self.managedObjectContext != nil) {
if ([self.managedObjectContext hasChanges]) {
BOOL success = [self.managedObjectContext save:&error];
if (!success) {
[Error showErrorByAppendingString:NSLocalizedString(@"UnableToSaveChanges", nil) withError:error];
} else {
//
}
}
}
// Unregister
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];
});
}
调用时,error=nil,success=NO,通过强制编译器通过异常,我得到以下结果:
CoreData:错误:获取PermenantIsForbjects期间出现异常:更新max pk失败:尝试写入userInfo为{NSSQLiteErrorDomain=1032的只读数据库;
}
我在谷歌上搜索过“NSSQLiteErrorDomain=1032”、“获取PermenantisForbjects”和“CoreData只读数据库”。看起来每个对象的主键都是相同的,但我正在设置这个值,我相信sqlite是一样的。我还没有找到任何解决办法来帮助解决这个问题。我确实在启动时传递了参数,“并发调试1”设置为on
我还没有实现GetainPermenantisProjects,我搜索了整个项目,找不到它的实现,所以我认为CoreData正在使用它
saveContext方法是在主队列上调用的,因为我的前辈就是这样编写代码的,我现在没有时间处理它
调用saveContext的方法(从后台线程):
NSSQLiteErrorDomain
键表示此错误来自SQLite,核心数据正在将其传回给您:
SQLITE_READONLY_DBMOVED错误代码是SQLITE_READONLY的扩展错误代码。SQLITE_READONLY_DBMOVED错误代码表示无法修改数据库,因为数据库文件在打开后已被移动,因此,如果进程因回滚日志命名不正确而崩溃,则任何修改数据库的尝试都可能导致数据库损坏
…这似乎意味着SQLite正在使持久存储文件成为只读文件,因为自从它被打开以来发生了一些事情,SQLite正在尝试防止数据损坏
我没有看到你发布的代码中有任何明显的错误,至少就错误代码描述而言。因此,我想知道,您是否在其他任何地方做了任何会直接影响持久存储文件的事情(即以任何方式触摸文件,而不是通过核心数据获取/保存调用)
错误代码描述中提到的回滚日志使我怀疑将
journal\u mode
设置为TRUNCATE
是否相关。如果是我,我会删除它(我不知道它在这里要实现什么),或者将它设置为DELETE
。至少出于测试目的,希望能够更好地理解问题。您是如何创建持久存储的,SQLite文件位于何处?@Wain更新了问题,并给出了对您问题的回答。希望这能让事情更清楚。汤姆,谢谢!因此,正是将日志模式设置为“删除”解决了这个问题。我删除了您回答后的选项,这似乎解决了问题,但当时,我添加到DB中的新实体只有在我保存功能之前存在于MOM中的实体时才会持续存在。我以为这个问题已经解决了,我正在做其他的事情,但是今天我添加了这个选项,并将其设置为删除,似乎就这样做了。谢谢现在来研究一下为什么。。。
- (NSMutableArray *)convertRawStepDataTo:(NSMutableArray*)steps
withDates:(NSMutableArray*)dates
inManagedObjectContext:(NSManagedObjectContext*)theMOC {
NSMutableArray *theStepsArray = [[NSMutableArray alloc] init];
// prepare values for chart
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
StepSelector *theSelector = [[StepSelector alloc] init];
NSString* apiSelectionForStep = [theSelector getCurrentSelectionString];
for (int iter = 0; iter < steps.count; iter++) {
NSNumber *currStepValue = [steps objectAtIndex:iter];
// NSNumber *stepCountforIter = [NSNumber numberWithLong:[[steps objectAtIndex:iter] longValue]];
NSNumber* dateForIter = [NSNumber numberWithLong:[[dates objectAtIndex:iter] longLongValue]];
Step *step = [delegate addStepObjectToPersistentStorewithAPI:apiSelectionForStep
andStep:stepCountforIter
andDate:dateForIter
forMOC:theMOC];
[theStepsArray addObject:step];
if (VERBOSE) {
NSLog(@"This is step number %d, with object ID: %@", count, [theMOC objectWithID:step.objectID]);
count++;
}
}
[delegate saveContext];
return theStepsArray;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [self getStoreURL];
// Rollback journalling mode...
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES],NSInferMappingModelAutomaticallyOption,
NSFileProtectionComplete, NSFileProtectionKey,
@{@"journal_mode": @"TRUNCATE"}, NSSQLitePragmasOption, nil];
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
NSError *error = nil;
self.persistentStore = [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error];
if (!self.persistentStore) {
NSLog(@"Error: %@",error);
[Error showErrorByAppendingString:NSLocalizedString(@"UnableToFindDatabaseFile", nil) withError:error];
}
return persistentStoreCoordinator;
}
-(NSURL *)getStoreURL {
NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: kSQLFILENAME];
/*
Set up the store.
For the sake of illustration, provide a pre-populated default store.
*/
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the expected store doesn't exist, copy the default store.
if (![fileManager fileExistsAtPath:storePath]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:SQLFILEPATHRESOURCE ofType:@"sqlite"];
if (defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
}
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
return storeUrl;
}