gpt4 book ai didi

Android Realm for 循环 - RealmResults 在循环期间被删除

转载 作者:行者123 更新时间:2023-11-29 19:13:33 24 4
gpt4 key购买 nike

我有一些代码在 IntentService 中运行,用于上传图片。它首先获取“排队”等待上传的帖子,然后遍历这些帖子并进行同步 Retrofit 调用以上传图片。非常坦率的。引用代码:

final RealmResults<Post> posts = realm.where(Post.class)
.equalTo("uniqueCode", uniqueCode)
.equalTo("queued", true)
.isEmpty("url")
.findAll();

Log.d(TAG, "post count: " + posts.size());

if (posts != null && posts.size() > 0) {
for (int i = 0; i < posts.size(); i++) {
Log.d(TAG, "posts count now: " + posts.size());

Post post = posts.get(i);

Post submittedPost = api.uploadPhoto(<params>); // Retrofit call, which works fine

if (submittedPost != null) {
realm.beginTransaction();
post.setQueued(false);
post.setUrl(submittedPost.getUrl());
realm.commitTransaction();

sendBroadcastUpdate(); // This updates the UI in places
}
}
}

奇怪的是,每次它通过 for 循环时,结果的大小(在我上面的例子中是“帖子”)都会减少一 - 我的日志输出每次都会减少一,所以它只能通过一些结果。就好像每次我在循环期间提交 Realm 事务时,它都会更新我获取的查询结果,即使该数组设置为最终数组也是如此。

我确认如果我不设置这些值('queued' 和 'url')它就不会这样做。这告诉我它正在以某种方式更新结果。我尝试了不同的东西,例如 while 循环(即“while (posts.size() > 0)”),但它通过了其中的 2-3 个,然后突然间“posts”的大小"立即为 0,我看不出任何原因。

我也试过在循环前后执行开始/提交,但它产生了类似的结果。如果我在处理之前将其转换为数组,情况也是如此。好像总是通过其中的几个,然后size自动设置为0,所以退出循环。

这让我觉得很奇怪,特别是因为我将结果设置为“最终”——这是预期的行为吗?有没有人知道解决这个问题的方法?

作为引用,我们使用的是 Realm 版本:0.86。

最佳答案

在版本 < 0.89.0 或版本 >= 3.0.0* 的 Realm 版本中,这是预期的行为(请参阅 here)。

RealmResults是最新版本数据库的 View (对于满足给定条件的给定对象类型),事务本质上是“创建最新版本的数据库”,意思是 RealmResults开始看到每次修改后的新修改数据。

请参阅以下内容:

final RealmResults<Post> posts = realm.where(Post.class)
.equalTo("uniqueCode", uniqueCode)
.equalTo("queued", true) // <---- condition true
.isEmpty("url")
.findAll();


...

if (submittedPost != null) {
realm.beginTransaction();
post.setQueued(false); // <---- condition false
post.setUrl(submittedPost.getUrl());
realm.commitTransaction();

sendBroadcastUpdate(); // This updates the UI in places
}

当您创建交易时,您会开始看到最新版本,在这种情况下,RealmResults将不再包含具有 queued == false 的元素.

对于 Realm 0.88.3 或更早版本,您需要反向迭代 RealmResults,或者“在结果不为空时迭代”(在 0.89.0 破坏性更改终止之前我经常使用这种方法,但它会再次使用 3.0.0+,这很好)

realm.refresh(); // enforce the next RealmResults to be *definitely* up-to-date

final RealmResults<Post> posts = realm.where(Post.class)
.equalTo("uniqueCode", uniqueCode)
.equalTo("queued", true)
.isEmpty("url")
.findAll();

while(!posts.isEmpty()) {
Post post = posts.get(0);
Post submittedPost = api.uploadPhoto(<params>); // Retrofit call, which works fine
if (submittedPost != null) {
realm.beginTransaction();
post.setQueued(false);
post.setUrl(submittedPost.getUrl());
realm.commitTransaction();
sendBroadcastUpdate(); // This updates the UI in places
}
}

对于 Realm 3.0.0+,您可以使用 for(Post post : results) { (迭代器),或 you can use a collection snapshot直接。

final RealmResults<Post> results = realm.where(Post.class)
.equalTo("uniqueCode", uniqueCode)
.equalTo("queued", true) //
.isEmpty("url")
.findAll();
final OrderedRealmCollection<Post> posts = results.createSnapshot(); // <-- snapshot

for (int i = 0; i < posts.size(); i++) {
//...

*(老实说,中间的行为是一个 hack,其中 RealmResults 未同步以查看最新版本,3.0.0 必须撤消此 hack)

关于Android Realm for 循环 - RealmResults 在循环期间被删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44376579/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com