是否可以自定义@synthesized属性?

时间:2011-01-13 06:03:48

标签: iphone objective-c properties

我可能只是在这里有点懒,但请忍受我。这是我的情况。我有一个包含两个非原子保留属性的类。让我们说:

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

我在实现中按预期合成它们。我想要发生的是,每当调用日期的setter时,它也会对dateField执行某些操作(即它将dateField上的text属性设置为日期格式良好的版本)。

我意识到我可以通过执行以下操作在我的实现中手动覆盖日期的setter:

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

如果我可以让Objective C处理保留/释放周期,但仍然能够“注册”(缺少更好的术语)在retain / release /之后调用的自定义处理程序,那将是多么棒的设置发生了。我的猜测是不可能的。我的google-fu没有提出任何答案,所以我想我会问。

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:0)

你可以通过创建一个私有的ivar / property(好的,你必须将属性记录为私有,理想情况下使用一个明显的名称)来完成另一个名称:

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