防止 Realm 在更新 Object 时覆盖 属性
Prevent Realm from overwriting a property when updating an Object
我已经在 iOS 中为领域 object 设置了 REST API。但是,我发现在我的 object 中创建最喜欢的标志时存在问题。我创建了一个 favorite bool,但是每次从 API 更新 object 时,它都会再次将 favorite 设置为默认 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"
}
}
创建或更新
let pet = Pet()
pet.id = 2
pet.name = "Dog"
pet.type = "German Shephard"
try! realm.write {
realm.add(pet, update: true)
}
有两种方法可以解决这个问题:
1.使用忽略 属性:
你可以告诉 Realm 某个 属性 不应该被持久化。为了防止你的 favorite
属性 被 Realm 持久化,你必须这样做:
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
属性就不会变了
结论
这两种方法有一个很大的区别:
Ignored 属性: 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 <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. 如果您正在进行任何大批量更新,返回遍历每个对象是不切实际的,并且肯定会在过程中造成痛苦。
我希望这能为需要的人提供另一种选择。
我已经在 iOS 中为领域 object 设置了 REST API。但是,我发现在我的 object 中创建最喜欢的标志时存在问题。我创建了一个 favorite bool,但是每次从 API 更新 object 时,它都会再次将 favorite 设置为默认 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"
}
}
创建或更新
let pet = Pet()
pet.id = 2
pet.name = "Dog"
pet.type = "German Shephard"
try! realm.write {
realm.add(pet, update: true)
}
有两种方法可以解决这个问题:
1.使用忽略 属性:
你可以告诉 Realm 某个 属性 不应该被持久化。为了防止你的 favorite
属性 被 Realm 持久化,你必须这样做:
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
属性就不会变了
结论
这两种方法有一个很大的区别:
Ignored 属性: 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 <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. 如果您正在进行任何大批量更新,返回遍历每个对象是不切实际的,并且肯定会在过程中造成痛苦。
我希望这能为需要的人提供另一种选择。