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

The short version of the question:
У меня есть класс с кучей объявленных свойств, и я хочу отслеживать, были ли какие-либо изменения в нем, чтобы при вызовеsave метод, он не записывает в базу данных, когда это не нужно. Как мне обновитьisDirty имуществоwithout writing custom setters for all of the declared properties?

The longer version of the question:
Допустим, у меня есть такой класс:

@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;
}

Attempt 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: не называется (я не уверен, почему я думал, что так и будет, смеется).

Attempt 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
}  

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

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

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

Ответы на вопрос(5)

Ваш ответ на вопрос