KVC奇怪的行为

Gra*_*lex 2 objective-c key-value-observing

为什么这段代码工作正常:

NSArray* arr = @[[CALayer layer], [CALayer layer]];
NSString *sumKeyPath = @"@sum.bounds.size.width";
CGFloat totalSize = [[arr valueForKeyPath:sumKeyPath] floatValue];
Run Code Online (Sandbox Code Playgroud)

但是这段代码给出了错误:

NSArray* arr = @[[UIImage imageNamed:@"img1"], [UIImage imageNamed:@"img2"]];
NSString *sumKeyPath = @"@sum.size.width";
CGFloat totalSize = [[arr valueForKeyPath:sumKeyPath] floatValue];
Run Code Online (Sandbox Code Playgroud)

错误: [NSConcreteValue valueForUndefinedKey:]:此类不是键值宽度的键值编码兼容.

NSArray* arr = @[[UIView new], [UIView new]];
NSString *sumKeyPath = @"@sum.bounds.size.width";
CGFloat totalSize = [[arr valueForKeyPath:sumKeyPath] floatValue];
Run Code Online (Sandbox Code Playgroud)

给出同样的错误

Mar*_*n R 8

CALayer有一个特殊的实现valueForKeyPath:.例如,以下工作:

CALayer *layer = [CALayer layer];
id x0 = [layer valueForKeyPath:@"bounds"];
// --> NSValue object containing a NSRect
id y0 = [layer valueForKeyPath:@"bounds.size"];
// --> NSValue object containing a NSSize
id z0 = [layer valueForKeyPath:@"bounds.size.width"];
// --> NSNumber object containing a float
Run Code Online (Sandbox Code Playgroud)

但以下不起作用:

CALayer *layer = [CALayer layer];
id x = [layer valueForKey:@"bounds"];
// --> NSValue object containing a NSRect
id y = [x valueForKey:@"size"];
// --> Exception: '[<NSConcreteValue 0x71189e0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key size.'
Run Code Online (Sandbox Code Playgroud)

所以一般情况下,NSValue含有一个对象NSRectNSSize键值兼容.它只适用于CALayer因为valueForKeyPath:实现处理整个键路径,而不是评估第一个键并传递剩余的键路径.

UIImage没有特殊的实现valueForKeyPath:.因此

UIImage *img1 = [UIImage imageNamed:@"img1"];
id x1 = [img1 valueForKey:@"size"];
// --> NSValue containing a NSSize
Run Code Online (Sandbox Code Playgroud)

有效,但是

UIImage *img1 = [UIImage imageNamed:@"img1"];
id x1 = [img1 valueForKeyPath:@"size.width"];
Run Code Online (Sandbox Code Playgroud)

不起作用.