如何在RealmSwift

时间:2017-06-07 08:47:11

标签: swift realm

文档中的示例(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
    }

还有一件事对我很有意思:如果压缩失败会发生什么?存储太少是一个原因。我是否仍然可以访问数据并且只会跳过压缩?

2 个答案:

答案 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的配置我只是在应用启动时使用一次,所以每次都不会触发它。

以下是Realm github issue

的链接

如果压缩失败,应用程序将继续使用未压缩的数据库版本。