繁体   English   中英

是否可以复制 Realm 对象?

[英]Is it possible to make copy of Realm object?

我想像这样在后台线程中刷新 Realm 数据库:(因为我从 Webservice 获得了新数据)

 RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
[realm deleteAllObjects]; // !!
[Pubs createOrUpdateInRealm:[RLMRealm defaultRealm] withJSONArray:data];
[realm commitWriteTransaction];

问题是,在我删除和更新 Realm db 中的对象的同时,用户可以打开一些 Detail ViewController 指向某个同时已删除的 Realm 对象(Pubs),因此抛出异常。

我没有看到任何解决方案,除非总是当我想从 Detail 控制器或其属性访问 Realm 对象时,我总是需要做这样的事情:

(这意味着始终获取 Realm 对象,但这也可能会失败)

pub = [Pubs objectsWhere:[NSString stringWithFormat: @"pubId = %lu", (long)_selectedPubId]].firstObject;

但我没有使用这个解决方案。 我想最好是如果我可以在 Detail 视图控制器中调用这样的东西:

pub = [Pubs objectsWhere:[NSString stringWithFormat: @"pubId = %lu", (long)_selectedPubId]].firstObject;
pub = [pub safeCopy];

因此可以同时删除 PubRealmObject,但 pub 对象将单独存在于内存中(仅用于访问其数据属性)。

那么有人尝试过类似的东西吗?

或者甚至可能使用一些像这样的iOS SDK 方式?

我只需要像我说的那样访问数据属性,而不是使用领域对象方法操作,例如删除或更新数据库中的对象。

顺便说一句,我试图在主线程中调用 Realm db 的更新,但问题是它需要 5-7 秒(只有 1000 个 JSON 对象),所以它滞后于应用程序。 这就是为什么我认为对象的后台更新和安全复制可能会更好。

但是我认为即使在复制对象时它也会失败,那么解决方案是什么? (后台更新与 Realm 对象的安全访问)

让视图控制器依赖可以从其下方删除的数据模型通常不是一个好的设计模式。 可以通过检查其object.invalidated属性来检查 Realm 对象是否已被删除以避免异常。

在任何情况下,要创建 Realm 对象的分离副本,您需要做的就是:

RLMObject *copiedObject = [[RLMObject alloc] initWithValue:object];

这将创建对象的副本,但不会插入到任何 Realm 实例中。 请注意,如果对象链接到任何其他 Realm 对象,这些对象也不会被复制; 新对象将只指向现有副本。

但是我仍然觉得我需要提一下,您可能可以使从 Web 服务更新 Realm 的实现更智能一些,以避免需要这样做。

如果您的对象实现了一个主键,那么当您调用createOrUpdateInRealm ,现有的对象将使用新值进行更新。

祝你好运!

使用斯威夫特:

以前在这里回答

截至 2020 年 12 月,此问题尚无适当解决方案。 不过,我们有很多解决方法。

这是我一直在使用的一种,在我看来限制较少的一种。

  1. 使您的领域模型对象类符合可编码
class Dog: Object, Codable{
    @objc dynamic var breed:String = "JustAnyDog"
}
  1. 创建这个助手类
class RealmHelper {
    //Used to expose generic 
    static func DetachedCopy<T:Codable>(of object:T) -> T?{
       do{
           let json = try JSONEncoder().encode(object)
           return try JSONDecoder().decode(T.self, from: json)
       }
       catch let error{
           print(error)
           return nil
       }
    }
}
  1. 每当您需要 Realm 对象的分离/真正深层副本时调用此方法,如下所示:
 //Suppose your Realm managed object: let dog:Dog = RealmDBService.shared.getFirstDog()
 guard let detachedDog = RealmHelper.DetachedCopy(of: dog) else{
    print("Could not detach Note")
    return
 }
//Change/mutate object properties as you want
 detachedDog.breed = "rottweiler"

正如你所看到的,我们捎带在 Swift 的 JSONEncoder 和 JSONDecoder 上,使用 Codable 的强大功能,无论在我们的领域对象下有多少嵌套对象,都可以进行真正的深度复制。 只要确保你所有的 Realm 模型类都符合 Codable。

虽然它不是一个理想的解决方案,但它是最有效的解决方法之一。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM