(我的问题有点类似于this one,除了我没有使用UndoManager,并且建议的解决方案对我不起作用。)
我的应用从第三方应用导入数据并将其存储在内存中,直到用户保存为止。导入定期在后台线程上保存:自己的managedObjectContext。该MOC使用其父级NSPersistentDocument MOC的持久性存储协调器。为了避免写入磁盘上的临时文件,使用NSInMemoryStoreType类型添加持久性存储。当用户想要将数据实际保存到磁盘上的文件时,在NSPersistentDocument的writeToURL覆盖中调用migratePersistentStore withType:NSInMemoryStoreType。
只要我使用NSXMLStoreType进行书写和阅读(在下面的代码中为// 1和// 2),这一切都可以正常工作。
当我切换到NSSQLiteStoreType时,写入会生成一个包含所有正确数据的有效SQLite文件,但回读该文件失败并显示以下错误:
CoreData: error: Encountered exception I/O error for database at /a/b/c.dat. SQLite error code:14, 'unable to open database file' with userInfo {
NSFilePath = "/a/b/c.dat";
NSSQLiteErrorDomain = 14;
} while checking table name from store: <NSSQLiteConnection: 0x6080001e3300>
CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///a/b/c.dat options:{
NSMigratePersistentStoresAutomaticallyOption = 1;
NSReadOnlyPersistentStoreOption = 1;
} ... returned error Error Domain=NSCocoaErrorDomain Code=256 "The file couldn’t be opened." UserInfo=0x60800006df40 {NSSQLiteErrorDomain=14, NSUnderlyingException=I/O error for database at /a/b/c.dat. SQLite error code:14, 'unable to open database file'} with userInfo dictionary {
NSSQLiteErrorDomain = 14;
NSUnderlyingException = "I/O error for database at /a/b/c.dat. SQLite error code:14, 'unable to open database file'";
以下是相关的简化代码:
// NSPersistentDocument.m
- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError *__autoreleasing *)error {
NSError *err;
NSDictionary *opts = @{
NSMigratePersistentStoresAutomaticallyOption : @YES,// it doesn't matter if these options are set or not
NSReadOnlyPersistentStoreOption : @YES,
};
if (![self.managedObjectContext.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType //1
configuration:nil
URL:absoluteURL
options:opts
error:&err])
{
return NO;
} else {
return YES;
}
}
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation originalContentsURL:(NSURL *)absoluteOriginalContentsURL error:(NSError *__autoreleasing *)error {
NSDictionary *opts = @{
NSMigratePersistentStoresAutomaticallyOption : @YES,// it doesn't matter if these options are set or not
NSReadOnlyPersistentStoreOption : @YES,
};
NSError *err;
[self.managedObjectContext.persistentStoreCoordinator migratePersistentStore:self.managedObjectContext.persistentStoreCoordinator.persistentStores[0]
toURL:absoluteURL
options:opts
withType:NSSQLiteStoreType //2
error:&err];
return YES;
}
// ====================================
// NSOperation.m
- (void)main
{
[...]
self.managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
self.managedObjectContext.persistentStoreCoordinator = self.myDoc.managedObjectContext.persistentStoreCoordinator;
self.managedObjectContext.undoManager = nil;
[self.managedObjectContext.persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType
configuration:nil
URL:nil
options:nil
error:nil];
典型的数据库由30k个对象组成,使用XML时需要花费很长时间才能编写和读取,所以我需要使用SQLite类型。
欢迎任何建议。
答案 0 :(得分:0)
我通过在-writeToUrl方法中使用以下dict解决了这个问题:
NSDictionary *opts = @{NSSQLitePragmasOption: @{@"journal_mode":@"DELETE"}};