更新Object时防止Realm覆盖属性
我在iOS中为realm对象设置了一个REST API。 但是我发现在我的对象中创建一个喜欢的标志有一个问题。 我已经创建了一个最喜欢的bool,但是每次从API更新对象时,它都会将喜好设置为默认值false。 在这里,我希望此标志不会更新,因为只有本地存储了collections夹。 我怎样才能做到这一点?
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) }
有两种方法可以解决这个问题:
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将存储’favorite’属性,但不会更新。
我想部分更新是您的目的所需要的。
如果你想更明确,有第三种选择:
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) }
4. NSUserDefaults(或任何其他数据存储,真的)
我遇到了同样的问题,我选择了另一个更传统的选项,即将东西保存到另一个数据存储(NSUserDefaults)。 在我的情况下,我存储了用户上次查看项目的时间,并且在NSUserDefaults中存储这些数据是合适的。 我做了类似以下的事情:
首先,为要存储的对象定义一个唯一键( self
这里是正在查看和呈现的模型对象):
- (NSString *)lastViewedDateKey { // Note each item gets a unique key with _ 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 = ; NSDate *lastViewedDate = [userDefaults objectForKey:self.lastViewedDateKey]; if (!lastViewedDate || [createdOnDate compare:lastViewedDate] == NSOrderedDescending) { ... }
与上述解决方案相反:1。没有数据持久性。 2.这创建了另一个必须定义对象属性的地方,如果每次添加新属性时忘记更新此列表,都可能导致错误。 3.如果您正在进行任何大批量更新,那么返回每个对象并不是很实用,肯定会导致痛苦。
我希望如果他们需要,我会给别人另一种选择。