RestKit 和 CoreData 无法关闭日志模式的问题
Posted
技术标签:
【中文标题】RestKit 和 CoreData 无法关闭日志模式的问题【英文标题】:Issue with RestKit and CoreData unable to turn off journal mode 【发布时间】:2014-05-23 05:27:50 【问题描述】:我刚开始使用 RestKit 框架 v0.20.3 与直接使用 Core Data。我正在尝试关闭日志模式以在 SQLite 数据库浏览器中查看数据库。我使用以下代码将 NSSQLitePragmaOption 设置为 @@"journal_mode":@"delete":
NSDictionary *options = @ NSMigratePersistentStoresAutomaticallyOption:@YES,
NSInferMappingModelAutomaticallyOption:@YES,
NSSQLitePragmasOption : @@"journal_mode": @"delete"
;
NSError *error;
NSPersistentStore *persistentStore = [objectStore addSQLitePersistentStoreAtPath:storePath
fromSeedDatabaseAtPath:nil
withConfiguration:nil
options:options
error:&error];
然而,这似乎并没有关闭日志模式并删除 .sqlite-wal 文件。当我直接使用 Core Data 并添加此选项时,它可以完美运行。有什么我想念的吗?
【问题讨论】:
显示更多用于您的核心数据堆栈设置的代码以及此代码如何与 RestKit 链接。 【参考方案1】:我发现 addPersistentStoreWithType
在 RestKit 的其他地方被调用,并且需要具有相同的选项才能禁用日志。就我而言,我使用RKManagedObjectImporter
创建一个种子数据库,如下所示:
NSError * error = nil;
NSString * seedFilePath = [[NSBundle mainBundle] pathForResource:@"seed" ofType:@"json"];
NSString * documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString * path = [documentsPath stringByAppendingPathComponent:@"MyDB.sqlite"];
RKManagedObjectImporter * importer = [[RKManagedObjectImporter alloc] initWithManagedObjectModel:_objectManager.managedObjectStore.managedObjectModel storePath:path];
[importer importObjectsFromItemAtPath:seedFilePath withMapping:mapping keyPath:keyPath error:&error];
BOOL success = [importer finishImporting:&error];
if (success)
[importer logSeedingInfo];
else
RKLogError(@"Failed to finish import and save seed database due to error: %@", error);
即使对 RKManagedObjectStore 进行了上述更改,我仍然在这里看到 -shm 和 -wal 文件。它显然不关心用于创建_object_manager.managedObjectStore
类型为RKManagedObjectStore
的选项。
我发现,在RKManagedObjectImporter.m
中,createPersistentStoreCoordinator
方法也添加了自己的持久存储,所以我在其中添加了选项字典:
NSDictionary * options = @ NSSQLitePragmasOption : @ @"journal_mode" : @"DELETE" ;
NSPersistentStore *persistentStore = [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:options error:error];
if (! persistentStore)
return nil;
最终……嗯,这样做很关键,因为没有它,种子数据库将丢失数据。现在我的 -shm 和 -wal 文件不见了。谢谢,顺便说一句,上述答案帮助我找到了另一个位置。
【讨论】:
【参考方案2】:我遇到了同样的问题。在 ios 6 中运行的代码突然开始在 iOS 7 中显示一些错误(数据丢失)。
我添加了NSSQLitePragmasOption: @ @"journal_mode": @"DELETE"
选项 RKManagedObjectStore 对象,但我仍然面临这个问题。
所以,在经历的时候
- (NSPersistentStore *)addSQLitePersistentStoreAtPath:(NSString *)storePath
fromSeedDatabaseAtPath:(NSString *)seedPath
withConfiguration:(NSString *)nilOrConfigurationName
options:(NSDictionary *)nilOrOptions
error:(NSError **)error
RKManagedObjectStore.m 类的方法,我发现了这条评论
/** 组合配置和迁移似乎有问题。所以分两步来做:首先,附加存储没有配置,但有迁移选项;然后删除它并重新附加 WITH 配置,但不是迁移选项。 **/
这里“persistentStore”被重新初始化,“seedOptions”跳过了我提供的“选项”。 所以对于我的项目,我不需要任何配置,所以我在下面的行中进行了评论,它开始工作了。
if (! [self.persistentStoreCoordinator removePersistentStore:persistentStore error:error]) return nil;
NSDictionary *seedOptions = @ RKSQLitePersistentStoreSeedDatabasePathOption: (seedPath ?: [NSNull null]) ;
persistentStore = [self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nilOrConfigurationName URL:storeURL options:seedOptions error:error];
if (! persistentStore) return nil;
现在 wal 和 shm 文件没有生成,我的代码按预期工作。
希望这会有所帮助。
【讨论】:
以上是关于RestKit 和 CoreData 无法关闭日志模式的问题的主要内容,如果未能解决你的问题,请参考以下文章