【问题标题】:How to correctly use shouldCompactOnLaunch in RealmSwift如何在 RealmSwift 中正确使用 shouldCompactOnLaunch
【发布时间】:2017-06-07 08:47:11
【问题描述】:

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

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

【问题讨论】:

    标签: swift realm


    【解决方案1】:

    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 上打开一个问题,并提供详细的重现步骤。

    一旦您创建了具有特定 ConfigurationRealm 实例,通常最好的做法是避免事后更改该配置。您不应该创建两个不同的 Configuration 对象,一个带有压缩块,一个没有。 Realm 在内部缓存基于其 ConfigurationRealm 实例,因此您可能会遇到不可预知的行为。

    压缩不应该失败。唯一会成为问题的主要情况是,如果您的设备已经处于硬盘空间不足的边缘。根据该 Realm 中有多少空闲空间,压缩的 Realm 通常会明显更小,因此整个操作不需要 2 倍的存储大小。在 iOS 上,如果系统检测到其存储空间不足,这将触发“清理”阶段,在该阶段其他应用程序的 Caches 目录将被清除,这在绝大多数情况下足以缓解问题以完成该过程。

    如果所有这些都失败了,执行压缩的尝试将抛出异常;你的错误处理代码应该能够捕捉到。

    【讨论】:

      【解决方案2】:

      所以我的解决方案是创建配置。除了 shouldCompactOnLaunch 块之外,配置是 相同的。这个带有 shouldCompactOnLaunch 的配置我只是在应用启动时使用一次,所以它不会每次都被触发。

      这是Realm github issue的链接

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

      【讨论】:

      • 在应用启动时调用这个会延迟应用启动时间?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-21
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      相关资源
      最近更新 更多