2013-03-27 60 views
2

爲什麼這個代碼工作正常:KVC奇怪的行爲

NSArray* arr = @[[CALayer layer], [CALayer layer]]; 
NSString *sumKeyPath = @"@sum.bounds.size.width"; 
CGFloat totalSize = [[arr valueForKeyPath:sumKeyPath] floatValue]; 

但這個代碼給錯誤:

NSArray* arr = @[[UIImage imageNamed:@"img1"], [UIImage imageNamed:@"img2"]]; 
NSString *sumKeyPath = @"@sum.size.width"; 
CGFloat totalSize = [[arr valueForKeyPath:sumKeyPath] floatValue]; 

錯誤[NSConcreteValue valueForUndefinedKey:]:此類不是密鑰值符合密鑰寬度的編碼。

NSArray* arr = @[[UIView new], [UIView new]]; 
NSString *sumKeyPath = @"@sum.bounds.size.width"; 
CGFloat totalSize = [[arr valueForKeyPath:sumKeyPath] floatValue]; 

給予同樣的錯誤

回答

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 

但下面不工作:

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.' 

所以一般情況下,含有NSValue對象NSRectNSSize鍵值兼容。它僅適用於CALayer,因爲valueForKeyPath:實現將處理整個關鍵路徑,而不是評估第一個關鍵點並傳遞其餘關鍵路徑。

UIImage沒有針對valueForKeyPath:的特殊實施。因此

UIImage *img1 = [UIImage imageNamed:@"img1"]; 
id x1 = [img1 valueForKey:@"size"]; 
// --> NSValue containing a NSSize 

作品,但

UIImage *img1 = [UIImage imageNamed:@"img1"]; 
id x1 = [img1 valueForKeyPath:@"size.width"]; 

不起作用。

2

我認爲錯誤告訴你正是這樣的問題是什麼! 「這個類不是密鑰寬度的關鍵值編碼。」

+0

有什麼區別? bounds-不是NSObject,size-不是NSObject。爲什麼第一個代碼工作正常第一種情況下的尺寸與第二種情況下的尺寸相同。 – Sk0prion 2013-03-27 11:21:46

+0

查看@ martin的回答。 'CALayer'在'valueForKeyPath:'(有時)中做了很多聰明的事情。 – 2013-03-27 12:17:18