KVC簡介
全稱是Key-value coding,翻譯成鍵值編碼。它提供了一種使用字符串而不是訪問器方法去訪問一個對象實例變量的機制。
KVC用法
- (id)valueForKey:(NSString *)key;
- (void)setValue:(id)value forKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
Key與KeyPath
Key較容易理解,就是要訪問的屬性名稱對應的字符串。
KeyPath是一個被點操作符隔開的用于訪問對象的指定屬性的字符串序列。
即通過KeyPath可以訪問屬性的屬性,比如KeyPath "address.street"將會訪問消息接收對象所包含的address屬性中包含的一個street屬性。其實KeyPath說白了就是我們平時使用點語法訪問某個對象的屬性時所寫的那個字符串。
點語法與KVC
在實現(xiàn)了訪問器方法的類中,使用點語法和KVC訪問對象其實差別不大,二者可以任意混用。但是沒有訪問起方法的類中,點語法無法使用,這時KVC就有優(yōu)勢了。
KVC對數(shù)值和結(jié)構(gòu)體型屬性的支持
KVC可以自動的將數(shù)值或結(jié)構(gòu)體型的數(shù)據(jù)打包或解包成NSNumber或NSValue對象,以達到適配的目的。
- 數(shù)值類型轉(zhuǎn)為NSNumber對象
+ (NSNumber *)numberWithChar:(char)value;
+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
+ (NSNumber *)numberWithShort:(short)value;
+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
+ (NSNumber *)numberWithInt:(int)value;
+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
+ (NSNumber *)numberWithLong:(long)value;
+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
+ (NSNumber *)numberWithLongLong:(long long)value;
+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
+ (NSNumber *)numberWithFloat:(float)value;
+ (NSNumber *)numberWithDouble:(double)value;
+ (NSNumber *)numberWithBool:(BOOL)value;
+ (NSNumber *)numberWithInteger:(NSInteger)value NS_AVAILABLE(10_5, 2_0);
+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value NS_AVAILABLE(10_5, 2_0);
- 基本結(jié)構(gòu)類型轉(zhuǎn)為NSValue
+ (NSValue *)valueWithCGPoint:(CGPoint)point;
+ (NSValue *)valueWithCGSize:(CGSize)size;
+ (NSValue *)valueWithCGRect:(CGRect)rect;
+ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform;
+ (NSValue *)valueWithUIEdgeInsets:(UIEdgeInsets)insets;
+ (NSValue *)valueWithUIOffset:(UIOffset)insets NS_AVAILABLE_IOS(5_0);
- 自定義結(jié)構(gòu)類型轉(zhuǎn)為NSValue
//將int轉(zhuǎn)成NSValue
NSValue *value = [NSValue valueWithBytes:&result objCType:@encode(int)];
//將NSValue轉(zhuǎn)成int
[value getValue:&result];
KVC相關集合運算符
集合運算符是一個特殊的Key Path,可以作為參數(shù)傳遞給valueForKeyPath:方法,注意只能是這個方法,如果傳給了valueForKey:方法則會崩潰。
運算符是一個以@開頭的特殊字符串,格式如下圖所示:
簡單集合運算符
簡單集合運算符共有@avg,@count,@max,@min,@sum5種,目前還不支持自定義。
舉例說明,要獲取amount的平均值可以這樣:
NSNumber *transactionAverage = [transactions valueForKeyPath:@"@avg.amount"];
對象運算符
比集合運算符稍微復雜,能以數(shù)組的方式返回指定的內(nèi)容,一共有兩種:
@distinctUnionOfObjects
@unionOfObjects
區(qū)別是前者返回的元素都是唯一的,是去重以后的結(jié)果;后者返回的元素是全集。
KVC如何訪問屬性值
KVC再某種程度上提供了訪問器的替代方案。不過訪問器方法是一個很好的東西,以至于只要是有可能,KVC也盡量再訪問器方法的幫助下工作。
為了設置或者返回對象屬性,KVC按順序使用如下技術:
- 檢查是否存在-<key>、-is<key>(只針對布爾值有效)或者-get<key>的訪問器方法,如果有可能,就是用這些方法返回值;
檢查是否存在名為-set<key>:的方法,并使用它做設置值。對于-get<key>和-set<key>:方法,將大寫Key字符串的第一個字母,并與Cocoa的方法命名保持一致; - 如果上述方法不可用,則檢查名為-_<key>、-_is<key>(只針對布爾值有效)、-_get<key>和-_set<key>:方法;
- 如果沒有找到訪問器方法,可以嘗試直接訪問實例變量。實例變量可以是名為:<key>或_<key>;
- 如果仍為找到,則調(diào)用valueForUndefinedKey:和setValue:forUndefinedKey:方法。這些方法的默認實現(xiàn)都是拋出異常,我們可以根據(jù)需要重寫它們。