cxa*_*cxa 12 setter properties objective-c key-value-observing
简而言之,当属性值发生变化时,我必须更新代码中的一些逻辑,例如:
- (void)setProp:(NSString *)theProp
{
if (prop != theProp){
[prop release];
prop = [theProp copy];
[self myLogic];
}
}
Run Code Online (Sandbox Code Playgroud)
要么:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([keyPath isEqualToString:@"prop"]){
[self myLogic];
}
}
Run Code Online (Sandbox Code Playgroud)
哪种方式最好,为什么?
编辑:我完全采用第二种方式,因为我不知道编译器会@synthesize为我生成指令,我选择相信编译器比我欠的setter实现更聪明,因此我不会破坏某些东西.
艰难的决定,恕我直言,这两种选择都很糟糕。
\n\n第一个强制您编写自己的 setter,这是一组\xc2\xa0lot 样板代码。(更不用说如果您希望相关属性的 KVO 正常工作,您还必须记住使用willChangeValueForKey:和来触发 KVO 通知。)didChangeValueForKey:
第二个选项也相当重量级,您的实现还不够。如果你的超类也有一些 KVO 怎么办?您\xe2\x80\x99d 必须调用super处理程序中的某个位置。如果没有,您确定您的超类不会改变\xe2\x80\x99t吗?(有关 KVO 的更多信息,请参阅相关问题。)
有时,您可以使用其他方法来回避问题,例如绑定(如果您\xe2\x80\x99 使用的是 Mac)或普通通知(您可以发布模型更改的通知,所有感兴趣的各方都应该刷新)。
\n\n如果您有很多像这样的重新计算并且不能找到任何更好的方法,我会尝试编写一个具有更好观察支持的超类,其接口如下:
\n\n[self addTriggerForKeyPath:@"foo" action:^{\n NSLog(@"Foo changed.");\n}];\nRun Code Online (Sandbox Code Playgroud)\n\n这将需要更多的工作,但它会让你的类清晰地分开,并且你可以在一个地方解决所有与 KVO 相关的问题。如果没有足够的重新计算属性来使其有价值,则 I\xc2\xa0 通常采用第一个解决方案(自定义设置器)。
\n| 归档时间: |
|
| 查看次数: |
3333 次 |
| 最近记录: |