Как определить, был ли изменен объект (self )с множеством свойств?

Краткая версия вопроса:
У меня есть класс с кучей объявленных свойств, и я хочу отслеживать, были ли в нем какие-либо изменения, чтобы, когда я вызываю для него метод save, он не записывался в базу данных, когда это не нужно. Как обновить свойство isDirtyбез написания пользовательских сеттеров для всех объявленных свойств ?

Более длинная версия вопроса:
Допустим, у меня есть такой класс:

@interface MyObject : NSObject
{
@property (nonatomic, retain) NSString *myString;
@property (nonatomic, assign) BOOL     myBool;
//... LOTS more properties
@property (nonatomic, assign) BOOL     isDirty;
}

...

@implementation MyObject
{
@synthesize myString;
@synthesize myBool;
//... LOTS more synthesizes :)
@synthesize isDirty;
}

Попытка 1
Моей первой мыслью было реализовать setValue:forKey:вот так:

- (void)setValue:(id)value forKey:(NSString *)key {
    if (![key isEqualToString:@"isDirty"]) {
        if ([self valueForKey:key] != value) {
            if (![[self valueForKey:key] isEqual:value]) {
                self.isDirty = YES;
            }
        }
    }
    [super setValue:value forKey:key];
}

Это работает отлично, пока вы не установите значение напрямую с помощью установщика (, т.е.myObject.myString = @"new string";), и в этом случае setValue:forKey:не называется (Я не уверен, почему я думал, что это будет, лол ).

Попытка 2
Наблюдайте за всеми свойствами себя.

- (id)init
{
    // Normal init stuff
    // Start observing all properties of self
}

- (void)dealloc
{
    // Stop observing all properties of self
}

- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary *)change 
                       context:(void *)context
{
    // set isDirty to true
}  

Я почти уверен, что это сработает, но я думаю, что должен быть лучший способ. :)Я также хочу, чтобы это было автоматически, чтобы мне не приходилось вести список свойств для просмотра. Я легко могу заметить, что забываю добавить свойство в список при поддержке этого в будущем, а затем пытаюсь выяснить, почему мой объект иногда не сохраняется.

Надеюсь, я упускаю из виду гораздо более простой подход к этой проблеме!

Окончательное решение
Смотрите мой ответ ниже для моего окончательного решения этого. Он основан на ответе Джоша Касвелла, но является рабочим примером.

17
задан lnafziger 31 July 2012 в 20:50
поделиться