迁移持久性存储时出错

时间:2017-04-11 15:30:59

标签: macos sqlite cocoa core-data

在我的基于文档的应用程序中,我遇到了将持久存储从应用程序内文档文件夹迁移到当前用户所选文件夹中的其他位置的一些问题。

(代码简化)

我像这样初始化托管对象上下文

_moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[_moc setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[_moc setPersistentStoreCoordinator:coordinator];
[_moc setUndoManager:[self undoManager]];

我使用这些持久存储选项

NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1;
NSSQLitePragmasOption =     {
    "journal_mode" = DELETE;
};

并创建

store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:absoluteURL options:[options copy] error:error];

这个持久存储的位置是    文件:///Users/currentuser/Library/Containers/com.my.application.osx/Data/Documents/doc1.ext

然后我填写了一些偏好

NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
[[managedObjectContext undoManager] disableUndoRegistration];

NSEntityDescription *description = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = description;
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];

Settings *file = nil;

if (error == nil) {
    if ([results count]>0) {
        file = [results firstObject];
    } else {
        file = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context];

    }
    [Settings setEntityFromUserDefaults:&file];
}
_fileSettings = file;
[managedObjectContext processPendingChanges];
[[managedObjectContext undoManager] enableUndoRegistration];
[self syncFileModificationDate];

最后,当我尝试执行此操作时

NSPersistentStoreCoordinator *coordinator = [self.managedObjectContext persistentStoreCoordinator];
[coordinator migratePersistentStore:[coordinator.persistentStores firstObject] toURL:absoluteURL options:[coordinator.persistentStores firstObject].options withType:NSSQLiteStoreType error:&error2];

我在调试控制台中看到的内容

  

2017-04-11 18:09:32.336项目[36495:4118531] CoreData:   错误:(21)/ Users / dzawadsky / Documents / tmp中数据库的I / O错误   作者docs / doc1.ext。 SQLite错误代码:21,'无法打开   数据库文件'

     

2017-04-11 18:24:42.980 Project [36495:4118531] CoreData:错误: -   -addPersistentStoreWithType:SQLite配置:PF_DEFAULT_CONFIGURATION_NAME   网址:文件:///Users/dzawadsky/Documents/tmp%20author%20docs/doc1.ext   选项:{

NSInferMappingModelAutomaticallyOption = 1;

NSMigratePersistentStoresAutomaticallyOption = 1;

NSPersistentStoreRemoveUbiquitousMetadataOption = 1;

NSSQLitePragmasOption =     {
    "journal_mode" = DELETE;
}; 
     

} ...返回错误错误域= NSCocoaErrorDomain代码= 21"(null)"

     

UserInfo = {NSSQLiteErrorDomain = 21,NSUnderlyingException = I / O.   / Users / currentuser / Documents / tmp作者的数据库错误   文档/ doc1.ext。 SQLite错误代码:21,'无法打开数据库   使用userInfo字典{

文件'}
NSSQLiteErrorDomain = 21;

NSUnderlyingException = "I/O error for database at /Users/currentuser/Documents/tmp author docs/doc1.ext.  SQLite error
     

代码:21,'无法打开数据库文件'&#34 ;;

     

}

UPD

我已经尝试过另一种方式 -

[fileManager copyItemAtURL:itemAtURL toURL:absoluteURL error:&error2];

并设置

[super setFileURL:absoluteURL];

所以托管对象上下文的持久性存储已被更改,但是当我向上下文添加一些托管对象并调用

[_moc save:&error];

错误重复 - 它仍然是我之前提到的错误

1 个答案:

答案 0 :(得分:1)

虽然问题很老, 我试图检查想要保存在CoreData中的所有内容。看来,在某些时候,在垃圾邮件撤消操作时,系统想要使用垃圾字段保存对象(但是我只有一个构造函数用于此对象,这会阻止创建此类字段的值)。试图检测此对象创建的位置,但未成功。所以,我阻止写这个垃圾对象。我已经完成了它,因为我记得使用某种类型的ManagedObjectContext的resetPending选择器,或者像那样的smth(不完全是 - [moc reset],它会清除你的MOC中的所有数据,小心)!