我正在使用Realm 2.1.1,并且自版本0.98以来一直在使用。
当用户进入后台时,有时会发生1小时或更长时间后,Realm数据库会丢失其所有对象。
已经检查过,我不会在后台进行任何保存或检索某些对象。
我在didFinishLaunchingWithOptions
上执行了对应用程序组的迁移,因为我使用的是Widget,我认为这导致了问题,因为它试图从另一个线程访问域。
领域数据库是加密的,所以我不知道它是否可以从钥匙串进入后台。
继承我的代码以初始化RealmDatabase:
class func migrateRealm() {
let config = RLMRealmConfiguration.defaultConfiguration()
config.schemaVersion = realmSchemeVersion()
config.migrationBlock = {(migration:RLMMigration, oldSchemaVersion: UInt64) in }
RLMRealmConfiguration.setDefaultConfiguration(config)
//Cache original realm path (documents directory)
guard let originalDefaultRealmPath = RealmEncrypted.realm().configuration.fileURL?.absoluteString else {
return
}
//Generate new realm path based on app group
let appGroupURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("app")!
let realmPath = appGroupURL.URLByAppendingPathComponent("default.realm")?.path ?? ""
//Moves the realm to the new location if it hasn't been done previously
if (NSFileManager.defaultManager().fileExistsAtPath(originalDefaultRealmPath) && !NSFileManager.defaultManager().fileExistsAtPath(realmPath)) {
do {
try NSFileManager.defaultManager().moveItemAtPath(originalDefaultRealmPath, toPath: realmPath)
//Set the realm path to the new directory
config.fileURL = NSURL(string: realmPath)
RLMRealmConfiguration.setDefaultConfiguration(config)
do {
try NSFileManager.defaultManager().removeItemAtURL(NSURL(string: originalDefaultRealmPath)!)
}
catch let error as NSError {
print("Ooops! Something went wrong deleting : \(error)")
}
}
catch let error as NSError {
print("Ooops! Something went wrong: \(error)")
}
}
else {
config.fileURL = NSURL(string: realmPath)
RLMRealmConfiguration.setDefaultConfiguration(config)
}
}
答案 0 :(得分:0)
在代码级别上,我可以看到的唯一可能导致问题的是您在内存中创建Realm
实例,然后尝试移动它。
执行此操作的特定行是guard let originalDefaultRealmPath = RealmEncrypted.realm().configuration.fileURL
。
Realm在内部缓存Realm
的副本,以便在后续调用中回收它们。因此,如果在内存中创建引用,然后在磁盘上移动物理文件,则会导致意外行为,甚至可能导致数据丢失。
最佳做法是尝试直接使用负责创建此Realm的Configuration
对象。如果您绝对需要访问Realm
然后想要在磁盘上移动文件,则可以将该代码封装在@autoreleasepool
中,以保证在移动文件之前从内存中删除Realm实例。 / p>
就您可能需要考虑的其他潜在事项而言:您可能需要change your file access permissions才能在后台写入Realm文件。
此外,您可能是正确的,因为您在应用程序背景化时也无法访问钥匙串值。显然another SO question that talks about this。