我有一个控制器注册为视图的很多属性的观察者.这是我们的-observeValueForKeyPath ::::方法:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void*)context
{
if( context == kStrokeColorWellChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kStrokeColorProperty];
}
else if( context == kFillColorWellChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kFillColorProperty];
}
else if( context == kBodyStyleNumChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kBodyStyleNumProperty];
}
else if( context == kStyleChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kStyleProperty];
}
else if( context == kStepStyleChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kStepStyleProperty];
}
else if( context == kFirstHeadStyleChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kFirstHeadStyleProperty];
}
else if( context == kSecondHeadStyleChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kSecondHeadStyleProperty];
}
如果这些陈述,实际上大约是其他的3倍.
您可以看到的一件事是每个块具有相同的代码,这使我认为可以优化它.
我最初的想法是有一个名为keyPathForContextDictionary的NSDictionary,其中键是具有Context后缀(类型为void *)的常量,值是适当的字符串常量,由属性后缀表示
那么这个方法只需要一行:
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:keyPathForContextDictionary[context]];
请注意,我需要使用某种数据结构来标识要使用的keyPath,并且我不能简单地使用传递给方法的keyPath参数.这是因为有多个视图具有我正在观察的相同属性(例如,颜色孔具有颜色属性).因此,每个视图都需要确定一个唯一的密钥路径,该密钥路径当前是根据上下文确定的
这个问题是你不能在NSDictionary中使用void *作为键.那么……有没有人对我能做什么有什么建议?
编辑:
这是一个如何定义常量的例子:
void * const kStrokeColorWellChangedContext = (void*)&kStrokeColorWellChangedContext;
void * const kFillColorWellChangedContext = (void*)&kFillColorWellChangedContext;
void * const kBodyStyleNumChangedContext = (void*)&kBodyStyleNumChangedContext;
void * const kStyleChangedContext = (void*)&kStyleChangedContext;
NSString *const kStrokeColorProperty = @"strokeColor";
NSString *const kFillColorProperty = @"fillColor";
NSString *const kShadowProperty = @"shadow";
NSString *const kBodyStyleNumProperty = @"bodyStyleNum";
NSString *const kStyleProperty = @"style";
最佳答案 类型void *不是一个你需要匹配的类型,因为它是“通用指针”.它精确地用于上下文参数,以便您可以使用任何您喜欢的基础类型,包括对象类型.你所要做的就是进行适当的演员表演.
因此,您可以非常轻松地将kTHINGYChangedContexts更改为NSStrings或任何其他您喜欢的对象,然后将它们用作上下文中的键 – >键路径映射.
从…开始:
NSString * const kStrokeColorWellChangedContext = @"StrokeColorWellChangedContext";
注册观察时,您必须执行桥接演员:
[colorWell addObserver:self
forKeyPath:keyPath
options:options
context:(__bridge void *)kStrokeColorWellChangedContext];
然后当观察发生时,你做反向投射:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void*)ctx
{
NSString * context = (__bridge NSString *)ctx;
// Use context, not ctx, from here on.
}
然后从那里继续进行关键路径查找.