KVO和重构

时间:2013-01-16 12:25:39

标签: ios objective-c properties refactoring key-value-observing

让我们说:

@property NSNumber* number;

我的控制器正在观察:

- (void)observeValueForKeyPath:(NSString *)keyPath ...
{
    if ([keyPath isEqualToString:@"number"]) ...
}

我的问题是 - 您重构number属性的名称的方法是什么?

很明显,我需要在观察者代码中更新观察到的密钥,但是我怎样才能以智能/自动的方式进行,并且不会错过任何观察者来处理我的财产变更?

4 个答案:

答案 0 :(得分:3)

一种方法是为所有正在观察的属性声明字符串常量。使用这些常量来添加观察者并比较keypath。每当要重命名属性时,都应该更改这些字符串常量的值。

我认为完全雾化是不可能的。

答案 1 :(得分:3)

好的,我会回复自己:)我的解决方案是Apurv解决方案和单元测试的混合。

这是:

1 对于MyClass中的每个观察到的属性,定义:

static NSString* MyClassPropertyNameNumber = @"number";

2 - (void)observeValueForKeyPath:(NSString *)keyPath ...实施中,使用定义的NSStrings。

- (void)observeValueForKeyPath:(NSString *)keyPath ...
{
    if ([keyPath isEqualToString:MyClassPropertyNameNumber]) ...
}

3 编写单元测试,检查MyClass对象是否响应setNumber:number选择器。

- (void)testMyClass
{
    SEL numberGetter = NSSelectorFromString(MyClassPropertyNameNumber);
    SEL numberSetter = NSSelectorFromString([NSString stringWithFormat:@"set%@:", MyClassPropertyNameNumber]);

    MyClass* testMyClass = [[MyClass alloc] init];
    if (![testMyClass respondsToSelector:numberGetter] || ![testMyClass respondsToSelector:numberSetter])
    {
        STFail(@"%@: %@ property name has changed! Please update your defined property name!", NSStringFromClass([MyClass class]), MyClassPropertyNameNumber);
    }
}

如果您更改属性名称,它将失败,并且不会更新已定义的属性名称。

我希望它会对某人有所帮助:)。

答案 2 :(得分:1)

为每个观察到的键路径定义一个变量,在注册时和观察者处理程序方法中将它们用作上下文:

static void * numberKVO = &numberKVO;
static void * letterKVO = &letterKVO;

...
[self addObserver:self 
       forKeyPath:@"kp.4.number" 
          options:NSKeyValueObservingOptionNew 
          context:numberKVO];
[self addObserver:self 
       forKeyPath:@"kp.4.letter" 
          options:NSKeyValueObservingOptionNew 
          context:letterKVO];   
...

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if (context == numberKVO) {
        ...
    } else if (context == letterKVO) {
        ...
    }
}

您可以修改属性和关键路径,而无需更改任何其他内容。

答案 3 :(得分:0)

在处理Core Data模型类时,

Mogenerator是一个很好的工具。它在以下位置为所有属性,关系和提取的属性生成NSStrings:

extern const struct ModelClassAttributes
extern const struct ModelClassRelationships
extern const struct ModelClassFetchedProperties