【问题标题】:Is it possible to customize @synthesized properties?是否可以自定义 @synthesized 属性?
【发布时间】:2011-06-08 07:34:24
【问题描述】:

我可能只是在这里有点懒惰,但请耐心等待。这是我的情况。我有一个具有两个非原子保留属性的类。比方说:

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

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

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

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

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

【问题讨论】:

    标签: iphone objective-c properties


    【解决方案1】:

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

    【讨论】:

    • 对,所以一个相关的问题是在哪里可以找到 @synthesize 在各种情况下(保留、分配、原子等)所做的示例代码
    • 酷,感谢您的回答。我在理论上知道 KVO,但是得到这个例子很棒。感谢您指出 setter 代码中的错误。我没有实际使用它就写出来了(显然)。我将编辑我的问题,以免对其他人产生误导。
    • 我一定是个盲人......你在代码中修复了什么?哦..问题一定已经编辑过了。
    • 是的,我编辑了我的问题。那是皱眉吗?我不想误导其他可能在没有阅读 Mike 的回答的情况下阅读我的问题的人。
    【解决方案2】:

    您可以通过使用另一个名称创建私有 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];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-24
      • 2016-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-08
      • 2019-11-01
      • 2016-12-09
      相关资源
      最近更新 更多