在autoreleasepool中使用realm的正确方法是什么?

fis*_*her 8 autorelease realm ios swift

这是文档关于使用GCD访问领域的说法:

"从调度队列访问Realm时,您应该使用显式自动释放池."

文档

我在我的应用程序中使用了这种做法,但我突然在控制台中看到以下消息:"RLMRealm实例在写入事务期间被释放".

它不会抛出错误,它只是默默地将它打印到控制台.没有任何内容写入数据库.

我在github上发现这个问题看起来非常相似.

我的问题是:我应该使用什么做法?在Realm文档中使用的那个或在github问题中找到的答案?

谢谢你的任何澄清.

TiM*_*TiM 10

GCD块管理自己的@autorelease池,但不能保证何时实际发生,并且在块本身完成后可能会发生相当长的时间(参见此SO答案)

Realm跨线程维护其所有实例的读锁(这是在另一个线程上打开写事务时仍然可以从Realm读取的结果),因此,建议在你'时显式释放一个Realm实例.重做,以便可以回收磁盘空间.

如果你不使用@autoreleasepool,就不会发生太糟糕的事情; 只是磁盘上Realm文件的大小会增加.

最佳做法是使用@autoreleasepool块,并确保在该块内提交所有写入事务.

@autoreleasepool {
    let realm = try! Realm()
    try! realm.write {
        // ... perform changes
    }
}
Run Code Online (Sandbox Code Playgroud)

通常建议使用realm.writeover beginWrite()/ commitWrite()因为它允许您安全地执行事务而不会忘记提交,并且还提供一些额外的错误处理.

GitHub上的问题是有一个逻辑路径会导致在@autoreleasepool提交写入事务之前退出.在这种情况下,您需要检查代码逻辑并确保没有类似的东西.

  • @hyouuu嗯,我从未尝试过那种API,所以我不确定.一般的想法是,您希望确保在调度队列完成其工作后尽快释放对象.它们在内存中停留的时间越长,发生的版本固定时间就越长(并且您的Realm文件大小会增加).无论如何,我认为这仍然比没有任何自动释放池处理要好得多. (2认同)