观察对具有KVO的对象的更改,上下文指针似乎不使用void*,但适用于NSString*

A O*_*A O 5 objective-c key-value-observing void-pointers

所以我有一个MainController,
在标题内我void*声明了这个:

static void *kStrokeColorWellChangedContext = &kStrokeColorWellChangedContext;
Run Code Online (Sandbox Code Playgroud)

在实现内部,我正在处理观察:

-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary *)change
                      context:(void*)context
{
   if( [keyPath isEqualToString:@"color"] )
   {
      if( context == kStrokeColorWellChangedContext )
      {
         [self setValue:[change objectForKey:@"new"] forKey:@"strokeColor"];
      }
   }
Run Code Online (Sandbox Code Playgroud)

然后我有一个具有此行的ViewController,它将MainController作为观察者添加到视图中

[self.strokeColorWell addObserver:self.toolController forKeyPath:@"color" options:NSKeyValueObservingOptionNew context:kStrokeColorWellChangedContext];
Run Code Online (Sandbox Code Playgroud)

因此,当视图的颜色发生变化时,它会通知MainController,并-observeValueForKey:使用键输入例程@"color"

但它无法进入if我正在检查的内部区块context.

如果我要换掉我void*NSString*代替,它就像我期望的那样工作.

怎么可能void*看起来有两个不同的地址存储在其中?

编辑: 也许这些价值void*可能有所帮助

结果po kStrokeColorWellChangedContext:

0x00000001005553e8

结果po context-observeValueForKey::

0x0000000100555ea0

objc [17775]:方法缓存已损坏.这可能是对无效对象的消息,也可能是其他地方的内存错误.
objc [17775]:接收器0x100555ea0,SEL 0x7fff899c8246,isa 0x100555ea0,缓存> 0x100555eb0,桶0x100566160,掩码0x0,占用0x0
objc [17775]:接收器0字节,桶0字节
objc [17775]:选择器'respondsToSelector:'

被抛出的异常可能会有一些提示,但我真的不明白它们

EDIT2:p代替的 输出po

(lldb) p context
(void *) $5 = 0x0000000100555ea0
(lldb) p kStrokeColorWellChangedContext
(void *) $6 = 0x00000001005553e8
Run Code Online (Sandbox Code Playgroud)

请注意,我非常有信心我正在调试正确的通知.
两个原因; 这keyPath是独特的,我认为价值是正确的.此外,如果我使用一个NSString*作为上下文它的工作原理

Ken*_*ses 5

问题是你在标题中定义kStrokeColorWellChangedContextstatic变量.导入该标头的每个翻译单元(基本上是源文件)将按该名称创建一个单独的变量,因为它已声明static,这对于文件范围的变量意味着什么.

因此,每个变量都有一个单独的地址,因为变量的值是它自己的地址,每个变量都有不同的值.

您可以在标头中声明变量并在实现中定义它,以便只有一个这样的变量.标题中的声明如下所示:

extern void * const kStrokeColorWellChangedContext;
Run Code Online (Sandbox Code Playgroud)

其中一个实现文件中的定义如下所示:

void * const kStrokeColorWellChangedContext = (void*)&kStrokeColorWellChangedContext;
Run Code Online (Sandbox Code Playgroud)

请注意,我已将变量const指向void.这不允许为它分配新值,因为它应该是一个常数.