一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Objective-C 鍵值編碼(Key-Value Coding)

 quasiceo 2015-04-03

Objective-C 鍵值編碼(Key-Value Coding)

時間 2013-08-05 14:24:23 原文  http:///archives/2744

鍵-值編碼( Key-Value Coding ),簡稱 KVC 。提供了一種間接訪問對象的方式。

在KVC中最常用的方法是: -valueForKey:-setValue:forKey: 。

Objective-C
1
2
NSString *name = [ car valueForKey : @"name" ] ;
NSLog ( @"%@" , name ) ;

valueForKey:首先查找以name命名的getter方法:-name。如果找不到,就會尋找名為_name或name的實例變量。所以通過使用KVC,即使沒有g(shù)etter方法,也不通過對象指針,照樣可以訪問屬性。

KVC還有一個特性,比如valueForKey:方法會自動將獲取的標(biāo)量值(int、float、struct)放入NSNumber或NSValue中(稱為“裝箱”)。

Objective-C
1
NSLog ( @"model year is %@" , [ car valueForKey : @"modelYear" ] ) ;

獲取的modelYear屬性值,實際上是一個int,但由于被valueForKey:自動“裝箱”,所以NSLog使用了%@格式符。

Objective-C
1
[ car setValue : @"Harold" forKey : @"name" ] ;

setValue:forKey:首先查找名為setName的setter方法,如果找不到,就尋找名為name或_name的實例變量,然后賦值。

如果想要設(shè)置一個標(biāo)量值,在調(diào)用setValue:forKey:之前需要先“裝箱”,因為setValue:forKey:方法會自動“拆箱”。

Objective-C
1
[ car setValue : [ NSNumber numberWithFloat : 25062.4 ] forKey : @"mileage" ] ;

鍵路徑( key path

KVC支持key path。對應(yīng)的方法是: setValue:forKeyPath:valueForKeyPath:

Objective-C
1
2
[ car setValue : [ NSNumber numberWithInt : 155 ] forKeyPath : @"engine.horsepower" ] ;
NSLog ( @"horsepower is %@" , [ car valueForKeyPath : @"engine.horsepower" ] ) ;

engine.horsepower就稱為key path,engine是car的實例變量,而horsepower是engine的實例變量。key path的深度不限,只取決于對象圖(object graph)。使用key path比使用方法嵌套更容易訪問“深層”的變量。

聚合操作( Aggregated Assault

看實例:

Objective-C
1
NSArray *pressures = [ car valueForKeyPath : @"tires.pressure" ] ;

tires是car的一個數(shù)組變量(NSMutableArray *tires)。在KVC中,上面這行代碼會訪問數(shù)組中的每一個對象的pressure的值,并將結(jié)果同樣組織成一個數(shù)組返回。

這個特性用起來會非常方便。但不支持?jǐn)?shù)組索引訪問,如:tires[0].pressure。

Smooth Operator

還可以在key path中添加一些有用的運(yùn)算。

Objective-C
1
2
3
NSNumber *count ;
count = [ garage valueForKeyPath : @"cars.@count" ] ;
NSLog ( @"We have %@ cars" , count ) ;

cars是garage(車庫)的一個數(shù)組變量(NSMutableArray *cars),在key path中的 @count 用于通知KVC機(jī)制計算對象總數(shù)。

Objective-C
1
2
3
NSNumber *sum ;
sum = [ garage valueForKeyPath : @"cars.@sum.mileage" ] ;
NSLog ( @"We have a grand total of %@ miles" , sum ) ;

@sum 用于對所有車輛的mileage(里程)求和。

Objective-C
1
2
3
NSNumber *avgMileage ;
avgMileage = [ garage valueForKeyPath : @"cars.@avg.mileage" ] ;
NSLog ( @"average is %.2f" , [ avgMileage ? oatValue ] ) ;

@avg 用于計算平均每輛車的行駛里程。

Objective-C
1
2
3
4
NSNumber *min , *max ;
min = [ garage valueForKeyPath : @"cars.@min.mileage" ] ;
max = [ garage valueForKeyPath : @"cars.@max.mileage" ] ;
NSLog ( @"minimax: %@ / %@" , min , max ) ;

@min@max 分別是求最小值和最大值的。

Objective-C
1
2
3
NSArray *manufacturers ; manufacturers =
   [ garage valueForKeyPath : @"cars.@distinctUnionOfObjects.make" ] ;
NSLog ( @"makers: %@" , manufacturers ) ;

@distinctUnionOfObjects 會計算一組對象(這里是make(制造商))的并集,刪除其中的重復(fù)值。

KVC的這些運(yùn)算雖然便捷,但速度較慢。如果key path有誤,編譯器并不能判斷出來,而是會出現(xiàn)運(yùn)行時錯誤。

Batch (批處理、批量操作)

相關(guān)方法: dictionaryWithValuesForKeys:setValuesForKeysWithDictionary: 。

Objective-C
1
2
3
4
car = [ [ garage valueForKeyPath : @"cars" ] lastObject ] ;
NSArray *keys = [ NSArray arrayWithObjects : @"make" , @"model" , @"modelYear" , nil ] ;
NSDictionary *carValues = [ car dictionaryWithValuesForKeys : keys ] ;
NSLog ( @"Car values : %@" , carValues ) ;

dictionaryWithValuesForKeys:方法為鍵@”make”、@”model”、@”modelYear”分別求值,然后構(gòu)造成一個NSDictionary對象返回。輸出結(jié)果可能為:

Objective-C
1
2
3
4
5
Car values : {
   make = Plymouth ;
   model = Valiant ;
   modelYear = 1965 ;
}

使用setValuesForKeysWithDictionary:批量修改。

Objective-C
1
2
3
4
5
6
7
NSDictionary *newValues = [ NSDictionary dictionaryWithObjectsAndKeys :
                               @"Chevy" , @"make" ,
                               @"Nova" , @"model" ,
                               [ NSNumber numberWithInt : 1964 ] , @"modelYear" ,
                               nil ] ;
[ car setValuesForKeysWithDictionary : newValues ] ;
NSLog ( @"car with new values is %@" , car ) ;

處理未定義的鍵

可以重寫valueForUnde?nedKey:和setValue:forUnde?nedKey:方法來處理未定義的鍵。(KVC在無法處理某個key時,會退回并詢問類該如何處理,默認(rèn)的實現(xiàn)是取消操作)

這里通過重寫如上兩個方法,使得class Garage可以設(shè)置和讀取任何key。

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@interface Garage : NSObject
{
   NSString *name ;
   NSMutableArray *cars ;
   NSMutableDictionary *stuff ;
}
@end // Garage
- ( void ) setValue : ( id ) value forUnde ? nedKey : ( NSString * ) key
{
   if ( stuff == nil ) {
     stuff = [ [ NSMutableDictionary alloc ] init ] ;
   }
   [ stuff setValue : value forKey : key ] ;
} // setValueForUnde?nedKey
- ( id ) valueForUnde ? nedKey : ( NSString * ) key
{
   id value = [ stuff valueForKey : key ] ;
   return ( value ) ;
} // valueForUnde?nedKey

《Objective-C基礎(chǔ)教程》讀書筆記

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国产精品国产亚洲看不卡 | 中国一区二区三区人妻| 免费性欧美重口味黄色| 狠狠亚洲丁香综合久久| 国自产拍偷拍福利精品图片| 国产成人精品一区二区在线看| 久久婷婷综合色拍亚洲| 亚洲国产精品久久网午夜| 国产福利在线播放麻豆| 国产一区麻豆水好多高潮| 日韩一本不卡在线观看| 中文精品人妻一区二区| 久久精品福利在线观看| 男人把女人操得嗷嗷叫| 国产精品白丝一区二区| 搡老熟女老女人一区二区| 国产一级片内射视频免费播放| 大屁股肥臀熟女一区二区视频| 欧美日本道一区二区三区| 日韩一级免费中文字幕视频| 麻豆视传媒短视频在线看| 国产精品二区三区免费播放心| 成年人免费看国产视频| 日韩黄色一级片免费收看| 99久久免费中文字幕| 东京热男人的天堂一二三区| 高清免费在线不卡视频| 亚洲一级二级三级精品| 麻豆国产精品一区二区| 久久福利视频视频一区二区| 欧美国产日韩变态另类在线看| 国产精品欧美激情在线| 国产一区日韩二区欧美| 香蕉尹人视频在线精品| 黄片美女在线免费观看| 日韩欧美国产精品中文字幕| 婷婷开心五月亚洲综合| 国产精品刮毛视频不卡| 麻豆蜜桃星空传媒在线观看| 亚洲欧美日韩国产成人| 国产精品视频第一第二区|