【问题标题】:Realm Cocoa can't update property of realm objects领域可可无法更新领域对象的属性
【发布时间】:2016-10-31 10:06:16
【问题描述】:

我正在使用 Realm Cocoa,在这里遇到了一个问题,我无法更新领域对象的属性,

RLMRealm *realm = [RLMRealm defaultRealm];

SomeObject *obj = [SomeObject objectForPrimaryKey: objectID];
if(obj){
  NSError *error;
  [realm transactionWithBlock:^{
    obj.someProperty = @YES;
  } error: &error];
}

SomeObject 是 RLMObject 的子类,someProperty 是 RLMBool 类型的属性

NSNumber<RLMBool> *someProperty

我检查了错误为nil,表示交易成功。 但是 someObject 永远不会按预期更新。

我还在Realm浏览器中检查了该属性,它也没有更新。(它总是假的)。

请帮忙。

【问题讨论】:

  • 这是什么线程?
  • @EpicPandaForce,在系统全局队列中

标签: realm


【解决方案1】:

对不起这个问题,我刚刚发现我不小心在另一个线程中将 someProperty 修改为@NO,这可能发生在问题中的代码块之后,代码块实际上按预期工作。也许一开始我不应该怀疑Realm。

【讨论】:

    【解决方案2】:

    您应该在事务块内执行查询。

      RLMRealm *realm = [RLMRealm defaultRealm];
    
      NSError *error;
      [realm transactionWithBlock:^{
        SomeObject *obj = [SomeObject objectForPrimaryKey: objectID];
        if(obj) {
            obj.someProperty = @YES;
        }
        // are you sure your object exists?
      } error: &error];
    

    【讨论】:

    • 我确定对象存在,并且执行了obj.someProperty = @YES。
    • 即便如此,您应该在交易块内部执行查询。这是一个常见的用户错误。
    • 这是不正确的。没有必要在 Realm Objective-C 的写入事务中包含查询。仅当您对需要持久保存到磁盘的 Realm 对象执行更改时,才需要写入事务。
    • @Tim 在后台线程上,最好确定在所有写操作之后的最新版本中,条件实际上是正确的(而不是保留到对象没有的旧版本还存在)
    • 在写事务中执行它不会那样做。但是,如果您在后台线程上并且需要确保最新的更改可用,您可以在执行查询之前通过调用 [realm refresh] 手动强制从 Realm 重新加载。 :) 领域写入事务是相当重要的操作,因为打开的事务将阻塞其他线程(包括主线程)上的任何其他待处理事务。最好的做法是尽量减少调用它们,并且一定要尽量减少在它们中完成的工作量。 :)