Как вы определяете, был ли изменен объект (я) с большим количеством свойств?
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
Смотрите мой ответ ниже для моего окончательного решения этого. Он основан на ответе Джоша Касвелла, но является рабочим примером.