我想定期在iOS上压缩Realm实例以恢复空间。我认为该过程是将数据库复制到临时位置,然后将其复制回来并使用新的default.realm文件。
我的问题是Realm()
就像一个单身人士并且回收对象,所以我无法关闭它并告诉它打开新的default.realm文件。
此处的文档(https://realm.io/docs/objc/latest/api/Classes/RLMRealm.html)建议我将所有Realm()调用包装在autorelease { }
中,但它不会很复杂。
答案 0 :(得分:21)
完全拆除所有检索到的模型访问器确实很棘手,但遗憾的是没有其他方法可以关闭Realm。
正如你写的"定期"根据您的使用情况,每个应用程序启动可能都足够了。
在启动应用程序时,在专用的自动释放池中打开Realm仍然相对容易,将压缩的副本写入不同的路径并用它替换default.realm文件。
func compactRealm() {
let defaultURL = Realm.Configuration.defaultConfiguration.fileURL!
let defaultParentURL = defaultURL.URLByDeletingLastPathComponent!
let compactedURL = defaultParentURL.URLByAppendingPathComponent("default-compact.realm")
autoreleasepool {
let realm = try! Realm()
realm.writeCopyToPath(compactedURL)
}
try! NSFileManager.defaultManager().removeItemAtURL(defaultURL)
try! NSFileManager.defaultManager().moveItemAtURL(compactedURL, toURL: defaultURL)
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
compactRealm()
// further setup …
return true
}
func compactRealm() {
let defaultURL = Realm.Configuration.defaultConfiguration.fileURL!
let defaultParentURL = defaultURL.deletingLastPathComponent()
let compactedURL = defaultParentURL.appendingPathComponent("default-compact.realm")
autoreleasepool {
let realm = try! Realm()
try! realm.writeCopy(toFile: compactedURL)
}
try! FileManager.default.removeItem(at: defaultURL)
try! FileManager.default.moveItem(at: compactedURL, to: defaultURL)
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
compactRealm()
// further setup …
return true
}
答案 1 :(得分:3)
@marius给出的答案有一个问题:打开的Realm可能仍然引用已删除的文件。这意味着某些写入可能会在旧(已删除)文件中结束,从而导致应用丢失数据。
compactRealm方法的正确实现如下(swift 3):
func compactRealm() {
let defaultURL = Realm.Configuration.defaultConfiguration.fileURL!
let defaultParentURL = defaultURL.deletingLastPathComponent()
let compactedURL = defaultParentURL.appendingPathComponent("default-compact.realm")
autoreleasepool {
let realm = try! Realm()
try! realm.writeCopy(toFile: compactedURL)
}
try! FileManager.default.removeItem(at: defaultURL)
try! FileManager.default.moveItem(at: compactedURL, to: defaultURL)
}
在我找到答案here
之前,这个问题一直让我发疯答案 2 :(得分:1)
嗯..好像这个问题已经过时了。 Realm去年秋天增加了一个自动紧凑功能。 Realm Docs / compacting-realms。我认为@marius所描述的唯一理由就是你需要在后台控制用户体验和压缩。
有关详情,请参阅此问题:How to correctly use shouldCompactOnLaunch in RealmSwift