我使用的是 Realm 2.1.1,并且从 0.98 版本开始使用。
有时发生的情况是,当用户进入后台时,经过 1 小时或更长时间后, Realm 数据库会丢失所有对象。
已经检查过了,我没有在后台执行任何保存或检索某些对象。
我在 didFinishLaunchingWithOptions
上执行了到应用程序组的迁移,因为我正在使用一个小部件,我认为这导致了问题,因为它尝试从另一个线程访问 Realm 。
Realm 数据库是加密的,所以我不知道是否可能是钥匙串(keychain)中的某些东西进入了后台。
这是我初始化 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)
}
}
最佳答案
在代码级别,我可以看到的唯一可能导致问题的地方是您在内存中创建一个 Realm
实例,然后尝试在之后移动它。
执行此操作的特定行是 guard let originDefaultRealmPath = RealmEncrypted.realm().configuration.fileURL
。
Realm 在内部缓存 Realm
的副本,以便它们可以在后续调用中回收。因此,如果您在内存中创建引用,然后将物理文件移动到磁盘上,则会导致意外行为,甚至可能导致数据丢失。
最佳实践是尝试直接使用负责创建此 Realm 的 Configuration
对象。如果您绝对需要访问 Realm,然后想要在磁盘上移动文件,您可以将该代码封装在 @autoreleasepool 中,以保证 Realm 实例从内存中删除在移动文件之前。
就您可能需要考虑的其他潜在事项而言:您可能需要change your file access permissions以便在后台写入 Realm 文件。
此外,您可能是正确的,因为当应用程序处于后台时您也无法访问钥匙串(keychain)值。显然有another SO question that talks about this .
关于ios - 有时后台 Realm 会丢失所有数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41106520/