首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以制作Realm对象的副本吗?

可以制作Realm对象的副本吗?
EN

Stack Overflow用户
提问于 2016-07-25 17:52:56
回答 2查看 4.8K关注 0票数 4

我想在后台线程中刷新Realm数据库,如下所示:(因为我从Webservice获得了新数据)

代码语言:javascript
复制
 RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
[realm deleteAllObjects]; // !!
[Pubs createOrUpdateInRealm:[RLMRealm defaultRealm] withJSONArray:data];
[realm commitWriteTransaction];

问题是,在我删除和更新领域数据库中的对象的同时,用户可以打开指向某个领域对象(Pubs)的一些详细ViewController,同时这些对象(Pubs)已经被删除,因此抛出异常。

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

(这意味着总是获取Realm对象,但这也可能失败)

代码语言:javascript
复制
pub = [Pubs objectsWhere:[NSString stringWithFormat: @"pubId = %lu", (long)_selectedPubId]].firstObject;

但是我没有使用这个解决方案。我认为最好的方法是,我可以像这样调用详细的视图控制器:

代码语言:javascript
复制
pub = [Pubs objectsWhere:[NSString stringWithFormat: @"pubId = %lu", (long)_selectedPubId]].firstObject;
pub = [pub safeCopy];

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

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

或者甚至可以使用某种iOS SDK方式like this

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

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

但是我在想,即使在复制对象的时候,它也会失败,那么解决这个问题的方法是什么呢?(后台更新vs领域对象的安全访问)

EN

回答 2

Stack Overflow用户

发布于 2016-07-26 13:19:59

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

在任何情况下,要创建领域对象的分离副本,您只需执行以下操作:

代码语言:javascript
复制
RLMObject *copiedObject = [[RLMObject alloc] initWithValue:object];

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

但我仍然觉得我需要提一提,您可以让您的web服务更新领域的实现更智能一点,以避免这样做的需要。

如果您的对象实现了a primary key,那么当您调用createOrUpdateInRealm时,现有对象将使用新值进行更新。

祝好运!

票数 12
EN

Stack Overflow用户

发布于 2020-12-24 17:50:28

使用Swift的

之前回答的here

到2020年12月为止,这个问题还没有得到适当的解决。不过,我们有很多变通方法。

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

  1. 使您的领域模型对象类符合可编码的

代码语言:javascript
复制
class Dog: Object, Codable{
    @objc dynamic var breed:String = "JustAnyDog"
}

  1. 创建此帮助器类

代码语言:javascript
复制
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. 在需要领域对象的分离/真正深度复制时调用此方法,如下所示:

代码语言:javascript
复制
 //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对象下有多少嵌套的对象,都可以进行真正的深度复制。只需确保所有的Realm Model类都符合可编码的。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38564603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档