更新Object时防止Realm覆盖属性

时间:2015-10-01 15:21:58

标签: ios swift realm

我已经在iOS中为realm对象设置了REST API。但是我发现在我的对象中创建一个喜欢的标志有一个问题。我已经创建了一个最喜欢的bool,但每次从API更新对象时,它都会将收藏夹设置为默认值false。在这里,我希望此标志不会更新,因为只有本地存储了收藏夹。我怎样才能做到这一点?

class Pet: Object{
    dynamic var id: Int = 1
    dynamic var title: String = ""
    dynamic var type: String = ""
    dynamic var favorite: Bool = false


    override class func primaryKey() -> String {
        return "id"
    }
}

CreateOrUpdate

let pet = Pet()
pet.id = 2
pet.name = "Dog"
pet.type = "German Shephard"


try! realm.write {
    realm.add(pet, update: true)
}

3 个答案:

答案 0 :(得分:20)

有两种方法可以解决这个问题:

<强> 1。使用忽略的属性:

您可以告诉Realm不应该保留某个属性。为了防止Realm持久保存favorite属性,您必须执行此操作:

class Pet: Object{
    dynamic var id: Int = 1
    dynamic var title: String = ""
    dynamic var type: String = ""
    dynamic var favorite: Bool = false

    override class func primaryKey() -> String {
        return "id"
    }

    override static func ignoredProperties() -> [String] {
       return ["favorite"]
   }
}

或者你可以

<强> 2。进行部分更新

或者您可以在更新Pet对象时明确告诉Realm应更新哪些属性:

try! realm.write {
  realm.create(Pet.self, value: ["id": 2, "name": "Dog", "type": "German Shepard"], update: true)
}

这样就不会更改favorite属性。

<强>结论

这两种方法有一个很大的区别:

忽略属性:Realm根本不会存储favorite属性。你有责任跟踪它们。

部分更新:Realm将存储“最喜欢的”&#39;财产,但它不会更新。

我认为部分更新是您的目的所需。

答案 1 :(得分:18)

如果你想更明确,有第三种选择:

第3。检索更新的当前值

// Using the add/update method
let pet = Pet()
pet.id = 2
pet.name = "Dog"
pet.type = "German Shephard"

if let currentObject = realm.object(ofType: Pet.self, forPrimaryKey: 2) {
    pet.favorite = currentObject.favorite
}

try! realm.write {
    realm.add(pet, update: true)
}

// Using the create/update method
var favorite = false
if let currentObject = realm.object(ofType: Pet.self, forPrimaryKey: 2) {
    favorite = currentObject.favorite
}

// Other properties on the pet, such as a list will remain unchanged
try! realm.write {
    realm.create(Pet.self, value: ["id": 2, "name": "Dog", "type": "German Shephard", "favorite": favorite], update: true)
}

答案 2 :(得分:0)

<强> 4。 NSUserDefaults(或任何其他数据存储,真的)

我遇到了同样的问题,我选择了另一个更传统的选项,即将内容保存到另一个数据存储(NSUserDefaults)。就我而言,我存储了用户上次查看项目的时间,并且在NSUserDefaults中存储这些数据是合适的。我做了类似以下的事情:

首先,为要存储的对象定义唯一键(self这里是正在查看和呈现的模型对象):

- (NSString *)lastViewedDateKey {
    // Note each item gets a unique key with <className>_<itemId> guaranteeing us uniqueness
    return [NSString stringWithFormat:@"%@_%ld", self.class.className, (long)self.itemId];
}

然后,当用户查看该项目时,将密钥设置为:

- (void)setLastViewedToNow {
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setObject:[NSDate date] forKey:self.lastViewedDateKey];
    [userDefaults synchronize];
}

后来,我这样使用它:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSDate *createdOnDate = <passed in from elsewhere>;
NSDate *lastViewedDate = [userDefaults objectForKey:self.lastViewedDateKey];
if (!lastViewedDate || [createdOnDate compare:lastViewedDate] == NSOrderedDescending) {
    ...
}

与上述解决方案相反: 1.没有数据持久性。 2.这创建了另一个必须定义对象属性的地方,如果每次添加新属性时忘记更新此列表,都可能导致错误。 3.如果您正在进行任何大批量更新,那么返回每个对象并不是很实用,肯定会引起痛苦。

我希望如果他们需要,我会给别人另一种选择。