观察 object w/ KVO 的变化,上下文指针似乎不适用于 void*,但适用于 NSString*
Observing changes to an object w/ KVO, context pointer doesn't seem to be working with a void*, but works with an NSString*
所以我有一个 MainController,
在 header 里面我有这个 void*
声明:
static void *kStrokeColorWellChangedContext = &kStrokeColorWellChangedContext;
我正在处理观察的实现内部:
-(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"];
}
}
然后我有一个 ViewController 有这一行,它将 MainController 作为观察者添加到视图
[self.strokeColorWell addObserver:self.toolController forKeyPath:@"color" options:NSKeyValueObservingOptionNew context:kStrokeColorWellChangedContext];
所以当视图的颜色改变时,它通知MainController,并进入-observeValueForKey:
例程,w/键@"color"
但是它无法进入内部 if
块,我正在检查 context
.
如果我用 NSString*
替换我的 void*
,它会按我预期的那样工作。
void*
怎么可能存储了两个不同的地址?
编辑:
也许 void*
的值可以帮助
po kStrokeColorWellChangedContext
的结果:
0x00000001005553e8
在-observeValueForKey:
中po context
的结果:
0x0000000100555ea0
objc[17775]: Method cache corrupted. This may be a message to an
invalid object, or a memory error somewhere else.
objc[17775]: receiver 0x100555ea0, SEL 0x7fff899c8246, isa 0x100555ea0, cache > 0x100555eb0, buckets 0x100566160, mask 0x0, occupied 0x0
objc[17775]: receiver 0 bytes, buckets 0 bytes
objc[17775]: selector 'respondsToSelector:'
那里抛出的异常可能有提示,但我真的一点都不懂
编辑2:
p
而不是 po
的输出
(lldb) p context
(void *) = 0x0000000100555ea0
(lldb) p kStrokeColorWellChangedContext
(void *) = 0x00000001005553e8
请注意,我pretty-very确信我正在调试正确的通知。
两个原因; keyPath
是唯一的,我看到该值是正确的。另外,如果我使用 NSString*
作为上下文,它会起作用
这对我有用 - kStrokeColorWellChangedContext
"has" 两个地址:它在内存中的位置和它的值,它们都是一样的!所以 kStrokeColorWellChangedContext
和 & kStrokeColorWellChangedContext
在整个程序中应该可以互换。
您是否尝试过单步执行 KVO 回调并查看 at/logging context
和 kStrokeColorWellChangedContext
的值?还有 keyPath
?
问题是您将 kStrokeColorWellChangedContext
定义为 header 中的 static
变量。每个导入 header 的翻译单元(基本上是源文件)都将创建一个 separate 变量,因为它被声明为 static
这就是它的意思文件范围内的变量。
因此,每个变量都有一个单独的地址,并且由于变量的值是它自己的地址,因此每个变量都有不同的值。
您可以在 header 中声明变量并在实现中定义它,这样只有一个这样的变量。 header 中的声明如下所示:
extern void * const kStrokeColorWellChangedContext;
其中一个实现文件中的定义如下所示:
void * const kStrokeColorWellChangedContext = (void*)&kStrokeColorWellChangedContext;
请注意,我已将变量设为 const
指向 void 的指针。这不允许为它分配新值,因为它应该是一个常量。
所以我有一个 MainController,
在 header 里面我有这个 void*
声明:
static void *kStrokeColorWellChangedContext = &kStrokeColorWellChangedContext;
我正在处理观察的实现内部:
-(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"];
}
}
然后我有一个 ViewController 有这一行,它将 MainController 作为观察者添加到视图
[self.strokeColorWell addObserver:self.toolController forKeyPath:@"color" options:NSKeyValueObservingOptionNew context:kStrokeColorWellChangedContext];
所以当视图的颜色改变时,它通知MainController,并进入-observeValueForKey:
例程,w/键@"color"
但是它无法进入内部 if
块,我正在检查 context
.
如果我用 NSString*
替换我的 void*
,它会按我预期的那样工作。
void*
怎么可能存储了两个不同的地址?
编辑:
也许 void*
的值可以帮助
po kStrokeColorWellChangedContext
的结果:
0x00000001005553e8
在-observeValueForKey:
中po context
的结果:
0x0000000100555ea0
objc[17775]: Method cache corrupted. This may be a message to an invalid object, or a memory error somewhere else.
objc[17775]: receiver 0x100555ea0, SEL 0x7fff899c8246, isa 0x100555ea0, cache > 0x100555eb0, buckets 0x100566160, mask 0x0, occupied 0x0
objc[17775]: receiver 0 bytes, buckets 0 bytes
objc[17775]: selector 'respondsToSelector:'
那里抛出的异常可能有提示,但我真的一点都不懂
编辑2:
p
而不是 po
(lldb) p context
(void *) = 0x0000000100555ea0
(lldb) p kStrokeColorWellChangedContext
(void *) = 0x00000001005553e8
请注意,我pretty-very确信我正在调试正确的通知。
两个原因; keyPath
是唯一的,我看到该值是正确的。另外,如果我使用 NSString*
作为上下文,它会起作用
这对我有用 - kStrokeColorWellChangedContext
"has" 两个地址:它在内存中的位置和它的值,它们都是一样的!所以 kStrokeColorWellChangedContext
和 & kStrokeColorWellChangedContext
在整个程序中应该可以互换。
您是否尝试过单步执行 KVO 回调并查看 at/logging context
和 kStrokeColorWellChangedContext
的值?还有 keyPath
?
问题是您将 kStrokeColorWellChangedContext
定义为 header 中的 static
变量。每个导入 header 的翻译单元(基本上是源文件)都将创建一个 separate 变量,因为它被声明为 static
这就是它的意思文件范围内的变量。
因此,每个变量都有一个单独的地址,并且由于变量的值是它自己的地址,因此每个变量都有不同的值。
您可以在 header 中声明变量并在实现中定义它,这样只有一个这样的变量。 header 中的声明如下所示:
extern void * const kStrokeColorWellChangedContext;
其中一个实现文件中的定义如下所示:
void * const kStrokeColorWellChangedContext = (void*)&kStrokeColorWellChangedContext;
请注意,我已将变量设为 const
指向 void 的指针。这不允许为它分配新值,因为它应该是一个常量。