文档中的示例(https://realm.io/docs/swift/latest/#compacting-realms)对我来说不是很清楚,因为我不知道压缩是否可以在应用程序使用期间一直调用,或者只能在启动时调用一次。下面的实现是正确的还是更好的做出一个单独的配置,包括在应用程序启动时调用一次shouldCompactOnLaunch。
如果我将shouldCompactOnLaunch添加到默认配置,我会看到每次创建领域实例时都会调用该块。
Realm.Configuration.defaultConfiguration = Realm.Configuration(schemaVersion: schemaVersion, migrationBlock: migrationBlock,shouldCompactOnLaunch: { totalBytes, usedBytes in
// totalBytes refers to the size of the file on disk in bytes (data + free space)
// usedBytes refers to the number of bytes used by data in the file
// Compact if the file is over 100MB in size and less than 50% 'used'
let oneHundredMB = 100 * 1024 * 1024
print ("totalbytes \(totalBytes)")
print ("usedbytes \(usedBytes)")
if (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.7{
print("will compact realm")
}
return (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.7
})
do {
// Realm is compacted on the first open if the configuration block conditions were met.
_ = try Realm(configuration: config)
} catch {
// handle error compacting or opening Realm
}
还有一件事对我很有意思:如果压缩失败会发生什么?存储太少是一个原因。我是否仍然可以访问数据并且只会跳过压缩?
答案 0 :(得分:2)
RLMRealmConfiguration
的头文件中还有其他信息:
/**
A block called when opening a Realm for the first time during the life
of a process to determine if it should be compacted before being returned
to the user. It is passed the total file size (data + free space) and the total
bytes used by data in the file.
Return `YES` to indicate that an attempt to compact the file should be made.
The compaction will be skipped if another process is accessing it.
*/
@property (nonatomic, copy, nullable) RLMShouldCompactOnLaunchBlock shouldCompactOnLaunch;
不可否认,我们应该在网站上的文档中更明显地说,只应在第一次创建表示特定Realm文件的Realm
实例时调用此块。
如果您肯定多次在同一个Realm
文件中看到此块被调用,请在Realm Cocoa GitHub page上打开一个问题,并提供重现的详细步骤。
使用特定Realm
创建Configuration
实例后,通常最好避免在事后改变该配置。您不应该创建两个不同的Configuration
对象,一个具有压缩块而另一个没有。 Realm在内部根据Realm
缓存Configuration
个实例,因此您可能会遇到不可预测的行为。
压缩不应该失败。如果您的设备已经处于耗尽硬盘空间的边缘,那么唯一会出现问题的主要情况就是如此。根据Realm中的空白空间,压缩的Realms通常要小得多,因此整个操作不需要2倍的存储大小。在iOS上,如果系统检测到其存储空间不足,则会触发“清理”阶段,其中将清除其他应用程序的Caches
目录,这在绝大多数情况下可以充分缓解问题以完成过程
如果所有这些都失败了,执行压缩的尝试将抛出异常;您的错误处理代码应该能够捕获。
答案 1 :(得分:1)
所以我的解决方案是创造配置。除了 shouldCompactOnLaunch 块的之外,配置相同。这个带有shouldCompactOnLaunch的配置我只是在应用启动时使用一次,所以每次都不会触发它。
的链接如果压缩失败,应用程序将继续使用未压缩的数据库版本。