关于这个问题的一些背景,我试图包括我认为可能与帮助理解上下文相关的内容。
我目前正在添加一个链接库,它使用Core数据来保存一些用户信息,并添加了一个功能,将一个实体添加到应用程序中已经存在的Core数据模型中。每个managedObjectContext在创建(验证)时都有自己的实例,也有自己的PSC和MOM,并且既不与其他实体交互(因此似乎是独立的)。
的全部代码,错误,和(我相信问题)是在应用程序的主要目标。(希望)不是新添加的链接库.
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: error: obtainPermenantIDsForObjects期间的异常:更新最大pk失败:尝试用userInfo { NSSQLiteErrorDomain = 1032;}写入只读数据库
我搜索过"NSSQLiteErrorDomain = 1032“、"obtainPermenantIDsForObjects”和"CoreData只读数据库“。看起来每个对象的主键都是相同的,但是我正在设置这个值,我相信sqlite是。我没有找到任何解决办法来帮助这一点。我确实在启动时传递了一个参数,“并发调试1”设置为on。
我没有实现obtainPermenantIDsForObjects,我搜索了整个项目,找不到它的实现,所以我认为CoreData正在使用它。
在主队列上调用saveContext方法,因为这是我的前辈推出代码的方式,我现在没有时间处理它。
调用saveContext的方法(从后台线程):
- (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;
}这就是我所能想到的所有可能有帮助的东西。主要目标中的MOC的来源是appDelegate,它是最初编写核心数据代码的地方。
编辑这里是请求的PSC代码。商店位于文档目录中。我发现这些对象被保存到持久存储中。但错误仍在发生。以下为PSC代码:
- (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;
}发布于 2016-08-26 16:45:43
NSSQLiteErrorDomain键意味着此错误来自SQLite,并且Core将它传回给您。SQLite定义错误1032如下
SQLITE_READONLY_DBMOVED错误代码是SQLITE_READONLY的扩展错误代码。SQLITE_READONLY_DBMOVED错误代码表示数据库无法修改,因为数据库文件自打开以来已被移动,因此,任何修改数据库的尝试都可能导致数据库损坏,如果进程因回滚日志无法正确命名而崩溃。
...which似乎意味着,SQLite之所以使持久存储文件读取,仅仅是因为它自打开以来发生了一些事情,而SQLite正试图防止数据损坏。
我没有在您发布的代码中看到任何明显是的错误,至少就错误代码描述而言是这样。因此,我想知道,您是否在任何其他地方做过会直接影响持久存储文件的事情(即,以任何方式触摸该文件,而不是通过Core数据获取/保存调用)?
错误代码描述中提到的回滚日志使我怀疑将journal_mode设置为TRUNCATE是否相关。如果是我,我会删除它(我不知道它打算在这里完成什么),或者将它设置为DELETE。至少为了测试的目的,无论如何,希望能更好地理解问题。
https://stackoverflow.com/questions/39155955
复制相似问题