Objective c 回应二传手

Objective c 回应二传手,objective-c,cocoa,Objective C,Cocoa,调用属性设置器时,响应数据更改的最佳方式是什么。例如,如果我有一个名为data的属性,那么当调用[object setData:newData]并仍然使用合成setter时,我该如何反应。本能地,我会像这样覆盖合成二传手: - (void)setData:(DataObject *)newData { // defer to synthesised setter [super setData:newData]; // react to new data ...

调用属性设置器时,响应数据更改的最佳方式是什么。例如,如果我有一个名为
data
的属性,那么当调用
[object setData:newData]
并仍然使用合成setter时,我该如何反应。本能地,我会像这样覆盖合成二传手:

- (void)setData:(DataObject *)newData {
    // defer to synthesised setter
    [super setData:newData];

    // react to new data
    ...
}

…但这当然没有意义-我不能像这样使用
super
。那么,处理这种情况的最佳方法是什么?我应该使用KVO吗?还是别的什么?

@synthesis创建默认访问器以便于使用。如果需要一些特殊操作,那么总是可以编写自己的访问器,而不是使用@synthesis。setter和getter不是从基类继承的,它们是由@synthesis指令创建的。所以您不需要(也不可以)调用super setData:(除非您确实创建了支持它的超类)


只需确保正确管理内存即可。包含有关如何为不同类型的内存策略(保留、分配或复制)管理内存的示例。

根据您需要的控制程度,有几种不同的方法。一种方法是观察自己的财产:

[self addObserver:self forKeyPath:@"data" options:0 context:nil];

- (void)observeValueForKeyPath:(NSString *)path ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if(object == self && [path isEqualToString:@"data"]) {
        //handle change here
    } else [super observeValueForKeyPath:path ofObject:object change:change context:context];
}
确保在dealloc或finalize方法中删除自己作为观察者的身份,如果之前没有

另一种方法是重写
-didChangeValueForKey:
。但是,如果对象上没有观察者,则可能不会调用此方法

- (void)didChangeValueForKey:(NSString *)key {
    [super didChangeValueForKey:key];
    if([key isEqualToString:@"data"]) {
        //handle change here
    }
}

您可以定义一个合成的“private”属性(将其放入
.m
文件中)


您现在可以像往常一样访问
someObject
“属性”,例如
object.someObject
。您还可以利用自动生成的
retain
/
release
/
copy
,与ARC兼容,并且几乎不会失去线程安全性

我试图找出是否有一种方法可以同时实现这两种功能:响应更改并保留
@synthesis
提供的实现。重写访问器和手动添加内存管理感觉是错误的。是否有一种更干净的方式来应对房地产的变化?这其实没有错,也没有不推荐的东西。我个人更喜欢这样。显然还有其他更好的方法。让我们看看其他人的建议。对于KVO,请检查。它说“您可以通过实现类方法automaticallyNotifiesObserversForKey:。”来控制子类属性的自动观察者通知”,尽管我自己还没有测试过。所以说不出实现起来有多困难。不建议重写
-didChangeValueForKey:
。如果您使用的是自动KVO通知(大多数类都这样做),则在添加观察者之前不会调用该方法。@Mike:这就是为什么它只是第二个选项。谢谢提醒,Mike@ughoavgfhw,也许你可以将这个警告编辑到你的答案中。KVO机制是否内置在
@synthesis
提供的getter和setter中?也就是说,如果我编写自己的getter并简单地释放和保留,我是否可能破坏KVO?据我所知,合成属性仅在
+automaticallyNotifiesObserversForKey:
返回
时生成自己的通知代码。所以,如果您想编写自己的setter方法(我想这就是您的意思),那么只需发布并保留即可。
@interface ClassName ()

// Declared properties in order to use compiler-generated getters and setters
@property (nonatomic, strong <or whatever>) NSObject *privateSomeObject;

@end
- (void) setSomeObject:(NSObject *)someObject {
  self.privateSomeObject = someObject;
  // ... Additional custom code ...
}

- (NSArray *) someObject {
  return self.privateSomeObject;
}