Dirty flags on Realm objects

梦想的初衷 提交于 2020-03-03 11:42:07

问题


Can anyone suggest a good pattern for implementing a dirty flag on Realm objects? Specifically, I would like every subclass of Realm Object to expose an isDirty flag that gets set whenever an instance of the class is modified and is cleared whenever the instance is written to the cloud (not the Realm). I'm working in Objective-C.

Possible solutions I can think of include the following:

  • Write a custom setter for every property of every objects. Set isDirty within each of those setters. Not very desirable.
  • Use KVO in some way. Two problems with this approach: (a) I don't fully understand how to implement this approach, and (b) Realm doesn't support KVO for managed objects (which are exactly the objects I need it for).
  • Use Realm notifications. Again, I don't have experience with these, and I'm not sure how to use them for this purpose.

回答1:


Short of simply having a non-managed isDirty property that you manually set after performing each write transaction, KVO would be the best way to go.

Setting custom setters would indeed be incredibly messy. You'd have to have a separate one for each property you wanted to track.

Realm notifications would only work if you were tracking a set of objects and wanted to be alerted if any were changed (using collection notifications) or if anything in the Realm changed.

With KVO, you could potentially get your object subclass itself to add observers to all of its properties, which are then channeled to one method whenever any of them change, this could then be used to mark the isDirty property.

@interface MyObject: RLMObject

@property NSString *name;
@property NSInteger age;

@property BOOL isDirty;

- (void)startObserving;
- (void)stopObserving;

@end

@implementation MyObject

- (void)startObserving
{
    NSArray *properties = self.objectSchema.properties;
    for (RLMProperty *property in properties) {
       [self addObserver:self forKeyPath:property.name options:NSKeyValueObservingOptionNew context:nil];
    }
}

- (void)stopObserving
{
    NSArray *properties = self.objectSchema.properties;
    for (RLMProperty *property in properties) {
       [self removeObserver:self forKeyPath:property.name];
    }
}

- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change 
                       context:(void *)context
{
    self.isDirty = YES;
}

+ (NSArray *)ignoredProperties {
    return @[@"isDirty"];
}

@end

Obviously you'd want to do more checking in here than I've done (to make sure isDirty truly needs to be set), but this should give you an idea.

There's no real way to automatically know when a managed Realm object has been created, so it would be best for you to manually start and stop observing as you need it.



来源:https://stackoverflow.com/questions/41603676/dirty-flags-on-realm-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!