Implement own setter or use KVO?

删除回忆录丶 提交于 2020-01-12 04:53:25

问题


In short, when the property value changing, I have to update some logic in my code, for example:

- (void)setProp:(NSString *)theProp
{
  if (prop != theProp){
    [prop release];
    prop = [theProp copy];
    [self myLogic];
  }
}

or:

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
  if ([keyPath isEqualToString:@"prop"]){
    [self myLogic];
  }  
}

Which is the best way, and WHY?

EDIT: I prefect the second way, because I don't know what the compiler will generate @synthesize directive for me, I choose to believe the compiler is more smarter than my owe setter implementation, hence I will not break something.


回答1:


Tough call, IMHO both options suck.

The first one forces you to write your own setter, which is a lot of boilerplate code. (Not to mention that you have to remember to also fire KVO notifications with willChangeValueForKey: and didChangeValueForKey: if you want KVO for the property in question to work.)

The second option is also quite heavy-weight and your implementation is not enough. What if your superclass also has some KVO in place? You’d have to call super somewhere in the handler. If not, are you sure your superclass won’t change? (More about KVO in a related question.)

Sometimes you can sidestep the issue using other methods like bindings (if you’re on a Mac) or plain notifications (you can post a notification that a model changed and all interested parties should refresh).

If you have many recalculations like this and can’t find any better way around, I would try to write a superclass with better observing support, with interface like this:

[self addTriggerForKeyPath:@"foo" action:^{
    NSLog(@"Foo changed.");
}];

This will take more work, but it will keep your classes cleanly separated and you can solve all KVO-related problems on one place. If there are not enough recalculated properties to make this worthwile, I usually go with the first solution (custom setter).




回答2:


The first snippet is the way to go, if you’re interested in changes in the same object. You only need to use the second if you are interested in changes to other objects, using it to observe self is overkill.




回答3:


In your case the best option is to add the logic inside the setter. Your setter implementation is correct if your property declaration is something like

@property (nonatomic, copy) YCYourClass *prop;

KVO is used normally when checking for changes on external objects properties.

NSNotifications are better suited to inform of events.



来源:https://stackoverflow.com/questions/5893392/implement-own-setter-or-use-kvo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!