Можно ли настроить свойства @synthesized? - PullRequest
4 голосов
/ 13 января 2011

Я, наверное, просто немного ленивый, но терпите меня. Вот моя ситуация. У меня есть класс с двумя неатомарными, сохраненными свойствами. Допустим,

@property (nonatomic, retain) UITextField *dateField;
@property (nonatomic, retain) NSDate *date;

Я синтезирую их, как и ожидалось в реализации. Я хочу, чтобы каждый раз, когда вызывался установщик даты, он также что-то делал с dateField (т. Е. Он устанавливал текстовое свойство dateField как красиво отформатированную версию даты).

Я понимаю, что могу просто вручную переопределить установщик даты в моей реализации, выполнив следующее:

- (void) setDate:(NSDate *)newDate {
    if (date != newDate) {
        [date release];
        date = [newDate retain];
        // my code to touch the dateField goes here
    }
}

Что было бы замечательно, если бы я мог позволить Objective C обрабатывать цикл сохранения / освобождения, но при этом иметь возможность «зарегистрировать» (из-за отсутствия лучшего термина) собственный обработчик, который будет вызываться после сохранения / освобождения / Набор случается. Я думаю, что это невозможно. Мой гугл-фу не дал никакого ответа на этот вопрос, поэтому я решил спросить.

Ответы [ 2 ]

4 голосов
/ 13 января 2011

KVO (наблюдение ключ / значение) может сделать это, вроде как, но в конечном итоге это будет еще больше кода, и, вероятно, не проще для чтения или записи.

Возможно, вы знакомы с KVO, но если вы (или другие) не знакомы: в вашей функции init вы бы сделали следующее:

[self addObserver:self forKeyPath:@"date" options:0 context:NULL];

Тогда вы бы реализовали это:

-(void)observeValueForKeyPath:(NSString*)keyPath 
                     ofObject:(id)object
                       change:(NSDictionary*)change
                      context:(void*)context
{
    if (object == self && [keyPath isEqualToString:@"date"]) {
        // code to touch the dateField goes here
    }
}

Наконец, в dealloc вы бы сделали это:

[self removeObserver:self forKeyPath:@"date"];

Как видите, это еще больше кода, и его сложнее понять. Не очень эффективно для того, чья цель - быть ленивым :-) Но KVO - это основная функция Objective-C для привязки данных. Существуют некоторые платформы (например, Flex), которые могут связывать данные с гораздо меньшим количеством кода, но в Objective-C требуется много работы.

Кстати, ничего страшного, но пример кода, который вы показали, содержит ошибки - вероятно, он должен выглядеть примерно так:

- (void) setDate:(NSDate *)newDate {
    if (date != newDate) {
        [date release];
        date = [newDate retain];
        // my code to touch the dateField goes here
    }
}
0 голосов
/ 13 января 2011

вы можете достичь, создав частное свойство ivar / property (хорошо, вы должны задокументировать свойство private, в идеале с использованием очевидного имени) с другим именем:

@property (nonatomic, retain) UITextField *dateField;
@property (nonatomic, retain) NSDate *date; // interface only
@property (nonatomic, retain) NSDate *datePRIVATE; // the real ivar.
...
@synthesize datePRIVATE;
- (void)setDate:(NSDate *)newDate {
    self.datePRIVATE = newDate;
    [self.dateField updateDisplayedDate:self.datePRIVATE];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...