Steve Wehba
Steve Wehba

Reputation: 181

Dirty flags on Realm objects

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:

Upvotes: 1

Views: 338

Answers (1)

TiM
TiM

Reputation: 15991

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.

Upvotes: 1

Related Questions