IOS 進階開發 KVC(一)

來源:互聯網
上載者:User

IOS 進階開發 KVC(一)

  熟練使用KVC 可以再開發過程中可以給我們帶來巨大的好處,尤其是在json 轉模型的時候,KVC讓程式員擺脫了繁瑣無營養的代碼堆積。減少代碼量就是減少出錯的機率。KVC 用起來很靈活,這種靈活的基礎是嚴格的命名要求。這種命名要求其實是一種約定。再程式的世界裡,約定的作用遠遠大於開發本身,良好的約定可以使程式員擺脫很多判斷,也減少了錯誤。KVC有如下幾點作用:

1)、直接賦值

使用KVC 可以對對象的某個屬性進行賦值。假定現在我們有一個Person 類,類中包含兩個屬性:一個是唯讀name 屬性,一個是Number類型的age屬性。

////  Person.h//  KVC////  Created by 鄧竹立 on 15-4-24.//  Copyright (c) 2015年 GiveMeFive. All rights reserved.//#import @interface Person : NSObject@property(nonatomic,copy,readonly)NSString* name;@property(nonatomic,assign)NSNumber *age;@end

當我們定義了屬性的時候,系統就為我們自動的產生了setter 和getter 方法。我們可以通過setter 和getter方法,或讀取或寫入數值。當然我們也可以用KVC 的方式進行讀寫資料。先看一下代碼,然後我們再簡述一下需要注意的問題。

#import "ViewController.h"#import "Person.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];        Person *person=[[Person alloc] init];        [person setValue:@"25" forKey:@"age"];    [person setValue:@"皮拉夫大王" forKey:@"name"];        NSLog(@"person 的名字是%@",person.name);    NSLog(@"person 的年領是%@",[person valueForKey:@"age"]);}@end

2015-04-24 20:40:13.286 KVC[6208:218095] person 的名字是皮拉夫大王

2015-04-24 20:40:13.287 KVC[6208:218095] person 的年領是25

如果你沒有接觸過KVC 的話,你大概會想:我擦,大王的腦子壞掉了吧?唯讀屬性怎麼可以賦值?!還有age屬性明明是NSNumber類型的,怎麼可以把字串賦給它?!沒錯,這就是我想說的,KVC 不但能夠賦值,而且還能破壞唯讀特性。當然這隻是我們需要注意的一個細節,更重要的是KVC 有自動裝箱(自動類型轉換)的功能,我們不需要去轉換類型了。由於開發過程中資料領域是字串的天下,所以這個自動裝箱的功能的確是極好的。

2)、支援鍵值路徑

什麼叫支援鍵值路徑?說白了就是支援嵌套。假如現在有一個書籍類,類中包含了書籍的名稱name。書籍可以被Person所擁有(就是可以作為person的屬性)

#import @interface Book : NSObject@property(nonatomic,copy)NSString* name;@end

那麼我們就可以這樣來用

    Person *person=[[Person alloc] init];    Book *myBook=[[Book alloc] init];    person.book=myBook;        [person setValue:@"程式員攤煎餅指南" forKeyPath:@"book.name"];        NSLog(@"%@",[person valueForKeyPath:@"book.name"]);

這裡的key直接使用點局分開就好了,注意一下:這裡使用的時keyPath,當然在 “ 1)屬性賦值” 中我們也可以使用keyPath,只不過再不必要的情況下使用keyPath會浪費效能而已。這裡沒啥可說的了,說多了都對不起我一度5毛的電費。

3)支援操作符

假如我們有10個字串,我們想求出這10個字串的總長度,我們可以使用KVC提供的操作符。

NSArray *books=@[@"鳥哥燒烤私房菜",@"程式員攤煎餅寶典",@"麻辣燙基礎教程"];NSLog(@"%@",[books valueForKeyPath:@"@sum.length"]);

這裡的@sum 是KVC 提供的,不是我們寫的。像這樣的函數共有5個@avg,@count,@max,@min,@sum。我們直接用就可以了。但是據說效率比用for迴圈慢。我沒有測試過,感興趣的話你可以測試一下。

4)錯誤攔截

對於我們前端程式員來說,後端程式員有時也是一個troubleMaker。他總是給你傳遞一些很奇怪的東西。比如給你傳遞一個id 屬性,或者什麼都不給你傳。如果有這樣一個json檔案 {“id”:"1"}。這是逼著我們把id作為資料模型的一個屬性的節奏啊!!老夫不願意啊!儘管作為屬性也不會報錯。屈服?還是抗爭?這是一個問題。但是好在前輩們已經給了我們答案。假如我們有一個Model類,類中的whoCare屬性就是本應命名為id 的屬性。我們還寫了一個字典轉模型的初始化方法。

@interface Model : NSObject@property(nonatomic,strong)id whoCare;-(instancetype)initWithDict:(NSDictionary *)dict;@end

那麼我們可以在.m檔案中重寫 -(void)setValue:(id)value forUndefinedKey:(NSString *)key 方法。這個方法會在字典轉模型時,系統找不到同名的屬性時調用。所以我們可以再這個方法中進行錯誤攔截,並進行賦值操作,這樣就不會報錯了。

#import "Model.h"@implementation Model-(instancetype)initWithDict:(NSDictionary *)dict{    if (self=[super init])    {        //忘了介紹了 字典轉模型的常用語句        [self setValuesForKeysWithDictionary:dict];    }    return self;}-(void)setValue:(id)value forUndefinedKey:(NSString *)key{    if ([key isEqualToString:@"id"])    {        self.whoCare=value;    }}@end

寫好了模型類,我們可以來測試一下。

#import "Model.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];    NSDictionary *dict=@{@"id":@"1"};        Model *model=[[Model alloc] initWithDict:dict];        NSLog(@"%@",model.whoCare);}@end

程式沒有崩潰,而且賦值成功。不信你看列印資訊

2015-04-24 21:12:00.676 KVC[6393:228807] 1

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.