sta*_*ugs 6 objective-c key-value-observing unions
我需要在使用KVO的Objective-C类上观察union-typed属性,但似乎我没有运气.我做了一些实验:只要我使用的是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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
输出:
2013-01-12 17:38:26.447 KVOTest[57522:303] keyPath vectorStructValue did change, object: <AppDelegate: 0x100614200>
Run Code Online (Sandbox Code Playgroud)
我做错了什么,或者这是Objective-C运行时/ KVO实现中的错误或遗漏功能?
注意:我知道我可以通过覆盖属性setter手动实现它,但这不是这个问题的重点.答案应该让我知道为什么自动KVO在这种情况下不起作用.
更新:为了清楚说明,这是一个简单的测试用例,它将struct属性上的KVO观察者与union属性上的KVO观察者进行比较.这些属性不相互关联.他们有独立的ivars和独立的内存支持商店.您可以删除struct属性并运行测试,结果仍然相同 - union属性没有KVO观察者事件.
bbu*_*bum 10
工会在KVO/KVC中被淘汰出局.留下下面的文字,因为它仍然很有趣.
KVO无法通过观察记忆或玩任何像这样棘手的恶作剧来工作.它的工作原理是动态创建一个子类,覆盖setter方法,并在调用willChange.../didChange...setter时自动调用方法.
因此,您实际上有2个属性与1个后备存储.然而,就KVO而言,它们完全相互隔离.
你想要的是依赖键.您可以使用+keyPathsForValuesAffectingValueForKey:在两个键之间创建依赖关系,以便调用setter将触发另一个属性的更改.
我不知道它是否支持共同依赖; 如果它支持有效的循环依赖.
或者,您应该能够覆盖setter以调用willChange/didChange其他属性(以及要更改的属性).
如果你想在相关的密钥将用来willChange/didChange射击的两个键,如果任一属性的变化.即如果你搞砸了结构,那么union会有效地改变,union属性的观察者应该看到一个意愿/做了改变以响应设置结构版本.
我刚试过它.你是对的.工会有点奇怪.它破碎了.所有这些仍然是正确的,但它没有好处.
雷达提交:rdar:// problem/13003794
哦......整洁.KVO w /工会根本不起作用.似乎运行时甚至不会识别该类具有完全被调用的键vectorUnionValue.
我补充说:
+ (NSSet *)keyPathsForValuesAffectingVectorStructValue
{
return [NSSet setWithObject:@"vectorUnionValue"];
}
+ (NSSet *)keyPathsForValuesAffectingVectorUnionValue
{
return [NSSet setWithObject:@"vectorStructValue"];
}
Run Code Online (Sandbox Code Playgroud)
这导致了运行时异常:
2013-01-12 12:05:11.877 djkdfjkdfjkdf[51598:303] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<AppDelegate 0x10010a520> valueForUndefinedKey:]: this class is not key value coding-compliant for the key vectorUnionValue.'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1501 次 |
| 最近记录: |