5

可以说我有:

@property NSNumber* number;

我的控制器正在观察:

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

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

很明显,我需要更新观察者代码中的观察键,但是我怎样才能以某种智能/自动的方式来完成它,并且不会错过任何观察者来处理我的属性的变化?

4

4 回答 4

3

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

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

于 2013-01-16T12:59:45.030 回答
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);
    }
}

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

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

于 2013-01-16T15:53:39.543 回答
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) {
        ...
    }
}

您可以在不更改任何其他内容的情况下修改属性和键路径。

于 2013-01-16T16:09:35.060 回答
0

在处理 Core Data 模型类时,Mogenerator是一个很棒的工具。它为所有属性、关系和获取的属性生成 NSString:

extern const struct ModelClassAttributes
extern const struct ModelClassRelationships
extern const struct ModelClassFetchedProperties
于 2013-05-16T09:03:46.870 回答