我可能只是在这里有点懒,但请忍受我。这是我的情况。我有一个包含两个非原子保留属性的类。让我们说:
@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没有提出任何答案,所以我想我会问。
答案 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];
}