iOS底層-KVC使用實踐以及實現原理

發表於2016-03-30

 

簡介

KVC(Key-value coding)鍵值編碼,顧名思義。額,簡單來說,是可以通過物件屬性名稱(Key)直接給屬性值(value)編碼(coding)“編碼”可以理解為“賦值”。這樣可以免去我們呼叫getter和setter方法,從而簡化我們的程式碼,也可以用來修改系統控制元件內部屬性(這個黑魔法且用且珍惜)。

1. 最簡單的使用例子

  • 假設有CYXModel類與CYXShopModel類,CYXModel裡面有nameproduct屬性,CYXShopModel裡面有productName屬性。

    • 不使用KVC,我們這樣訪問CYXModel的屬性
      • 取值:
      • 設值:
    • 使用KVC,我們可以這樣訪問CYXModel的屬性
      • 取值:
      • 設值:

    注: 這個簡單的例子,可能你看了覺得這並沒什麼卵用,下面我們來分析一下稍微有點卵用的例子吧。

    2. KVC字典轉模型的實現原理

    • 假設dict字典中有name,icon的Key,CYXModel模型類中必須要有同名的name,icon屬性與之相對應。
    • 我們使用[CYXModel setValuesForKeysWithDictionary:dict];進行字典轉模型。
    • setValuesForKeysWithDictionary:方法內部實現原理如下:
      • (1) 遍歷字典裡面所有的key和值,name,icon。
      • (2) 分別給屬性賦值
        • [CYXModel setValue:dict[@"name"] forKey:@"name"];
        • [CYXModel setValue:dict[@"icon"] forKey:@"icon"];
    • setValue:forKey:方法:給模型的屬性賦值
      • 賦值原理:
        • (1)去模型中查詢有沒有setIcon方法,就直接呼叫這個set方法,給模型這個屬性賦值[self setIcon:dict[@"icon"]];
        • (2)如果找不到set方法,接著就會去尋找有沒有icon屬性,如果有,就直接訪問模型中icon = dict[@"icon"];
        • (3)如果找不到icon屬性,接著又會去尋找_icon屬性,如果有,直接_icon = dict[@"icon"];
        • (4)如果都找不到就會報錯
          [<Flag 0x7fb74bc7a2c0> setValue:forUndefinedKey:]
    • 擴充套件:讀者可以去查查KVV(鍵值驗證),進一步理解報錯原因與容錯方法。

    注: 稍微有點卵用的看完,接下來說一個比較有卵用的用法,這個例子需要配合runtime來實現,有興趣可以看看,runtime內容不少,這裡就暫不介紹了,歡迎 關注,在下篇文字小結一下runtime。

    3. 修改系統控制元件內部屬性(runtime + KVC)

    • 有時候,UI會閒著沒事,會給你找點事情,例如,介面設計圖是這樣的:
      必奢商城首頁
    • 這。。怎麼感覺有點不同,這UIPageControl怎麼跟我平常用的不一樣?平常不都是這樣的??如下圖
      美麗說首頁
    • 首先想到的肯定是,檢視UIPageControl的標頭檔案,如下:
    • 臥槽,就這麼幾個屬性可以給我設的,不夠用啊兄弟。能不能給我個可以賦值UIImage物件的屬性?看來正常途徑使用系統的控制元件是設不了了,剩下的我感覺只有兩種方法(如有其它,歡迎指出),一種是自定義PageControl,這種方式看起來不簡單,各位有興趣可以去試試。另一種方式就是,通過runtime遍歷出UIPageControl所有屬性(包括私有成員屬性,runtime確實很強大)。
    • 使用runtime遍歷UIPageControl結果(下篇文字再談談runtime,這裡暫不解釋)如下列印:
    • 結果非常滿意,果然找到我想要的圖片設定屬性。
    • 然後通過KVC設定自定義圖片,實現了效果,程式碼如下:
    • 注:
      這裡只是拋磚引玉的講了個小例子,其他的神奇功能等待讀者去發現啦。

    提示: 在xib/Storyboard中,也可以使用KVC,下面是在xib中使用KVC把圖片邊框設定成圓角

    xib中設定KVC

相關文章