我需要在使用 KVO 的 Objective-C 类上观察联合类型的属性,但似乎我对此并不走运。我做了一些实验:只要我使用 C 结构,一切正常。一旦我用联合替换结构,自动 KVO 就不再起作用(observeValueForKeyPath
没有被调用)。
这是我的小测试课:
AppDelegate.h:
#import <Cocoa/Cocoa.h>
typedef union {
float data[3];
struct {
float x,y,z;
};
} vec3union;
typedef struct {
float x,y,z;
} vec3struct;
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet NSWindow *window;
@property (assign) vec3struct vectorStructValue;
@property (assign) vec3union vectorUnionValue;
@end
AppDelegate.m:
@implementation AppDelegate
@synthesize vectorStructValue = _vectorStructValue;
@synthesize vectorUnionValue = _vectorUnionValue;
- (void)dealloc
{
[super dealloc];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[self addObserver:self forKeyPath:@"vectorStructValue" options:NSKeyValueObservingOptionNew context:nil];
[self addObserver:self forKeyPath:@"vectorUnionValue" options:NSKeyValueObservingOptionNew context:nil];
self.vectorStructValue = (vec3struct){1,2,3};
self.vectorUnionValue = (vec3union){4,5,6};
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"keyPath %@ did change, object: %@", keyPath, [object description]);
}
@end
输出:
2013-01-12 17:38:26.447 KVOTest[57522:303] keyPath vectorStructValue did change, object: <AppDelegate: 0x100614200>
我做错了什么,或者这是 Objective-C 运行时/KVO 实现中的错误或缺失功能?
注意:我知道我可以通过覆盖属性设置器来手动实现它,但这不是这个问题的重点。答案应该让我知道为什么自动 KVO 在这种情况下不起作用。
更新:为了清楚起见,这是一个简单的测试用例,将结构属性上的 KVO 观察者与联合属性上的观察者进行比较。这些属性并不相互关联。他们有独立的 ivars 和独立的内存后备存储。您可以删除 struct 属性并运行测试,仍然是相同的结果 - 没有针对 union 属性的 KVO 观察者事件。