你如何在iOS上压缩Realm DB?

我想定期在iOS上压缩一个Realm实例来恢复空间。 我认为这个过程是将数据库复制到临时位置,然后将其复制并使用新的default.realm文件。

我的问题是Realm()行为像一个单身人士,并回收对象,所以我不能真正closures它,并告诉它打开新的default.realm文件。

这里的文档( https://realm.io/docs/objc/latest/api/Classes/RLMRealm.html )build议我在autorelease { }包装所有的Realm()调用,但是不能这么复杂。

完全拆除所有检索到的模型访问器可能确实很棘手,但不幸的是没有其他办法可以closures一个Realm。

正如你写的“定期”,每个应用程序的启动可能通常是足够的,这取决于你的使用情况。

在启动应用程序时,在专用的autoreleasepool中打开Realm应该还是比较容易的,将压缩的副本写入不同的path并用它replacedefault.realm文件。

Swift 2.1

 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 } 

Swift 3.0

 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 } 

@marius给出的答案有一个问题:打开的领域可能仍然引用已删除的文件。 这意味着一些写入可能会以旧的(删除的)文件结束,导致应用程序丢失数据。

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) } 

这个问题一直让我疯狂,直到我在这里find答案