Realm 隐蔽的跨线程问题

Realm 文档介绍,同一个 Realm 实例,可以被任意线程访问,即能够在任意线程进行写操作,写事务被包裹在 beginWritecommitWrite之间。不过在开始写事务到结束之前,只能由单一的线程访问 RealmObject 对象,否则会抛出跨线程访问异常。

在项目中遇到一个需求是,在写事务中读取数据对象之后,需要做一个异步操作,完成之后更新对象的状态。例如,上传本地数据失败重传处理,需要先读取同步失败的对象,再重传,成功后更新同步状态。

为了便于管理, Realm 的写事务可以用同一个串行队列,以闭包的形式将写事务(Task)异步分发(Dispatch)执行。上述需求需要嵌套的使用写事务来完成,伪代码请见配图。

realm-crash.jpg

然而,执行程序挂在 58 行,从线程堆栈看, 内部实际挂在Realm verify_thread();方法。原因是内层写操作被异步分发到另一个线程了,导致跨线程访问奔溃。

能想到的解决方法是,copy results 里面的每个 RealmObject 对象,放入新的数组,供另一个线程访问并更新。

这个问题的根本原因在于,没有意识到异步分发任务到同一个串行队列,并不能保证任务都在同一个线程上执行。虽然在学习队列使用的时候,有看过需要注意这一点,但是在实际使用中,还是被忽视了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容