[iOS]開發之-字典轉模型和KVC

来源:http://www.cnblogs.com/wanglekai/archive/2016/04/20/5410931.html
-Advertisement-
Play Games

需求一:將字典轉換成自己需的對象,對象的屬性是字典的key值,直接使用key值獲取數據存在兩個缺點,一是key值難以記憶,二是直接使用key值Xcode不會有智能提示,很容易導致未知的錯誤。使用模型時,可以直接通過點語法將需要的數據點出,保證數據準確無誤。使用模型的優點還在於存儲、傳值都比較方便,不 ...


需求一:將字典轉換成自己需的對象,對象的屬性是字典的key值,直接使用key值獲取數據存在兩個缺點,一是key值難以記憶,二是直接使用key值Xcode不會有智能提示,很容易導致未知的錯誤。使用模型時,可以直接通過點語法將需要的數據點出,保證數據準確無誤。使用模型的優點還在於存儲、傳值都比較方便,不容易出錯。最主要的是這也符合我們MVC和MVVM的設計模式。

 

註意:要使用模型就離不開KVC,假如我們從外界傳入一個字典,字典中有兩個 key對應的值是我們需要的,這兩個值分別是 “name”、“age”。要使用KVC的時候要註意模型的屬性一定要和字典中的key值相對應。比如字典中的“name”,那模型中就必須有一個name的屬性。這樣就可以使用KVC了,KVC的兩種方法:(下文都預設我們有兩個模型屬性,分別是name和age,傳入的字典預設為dict)

 

1. setValue(模型屬性, forKey:字典的key值)

eg:setValue(self.name, forKey:dict[“name”])

 

*這種賦值方法很麻煩,每需要一個key值就要打一遍該方法。這樣的賦值方式就和self.name = dict[“name”] 的區別不是太大

2. setValuesForKeysWithDictionary(傳入的字典)         

eg: setValuesForKeysWithDictionary(dict)

*直接完成賦值,其實setValuesForKeysWithDictionary(傳入的字典),它預設也是調用setValue(模型屬性, forKey:字典的key值 ),遍歷字典一一給模型屬性賦值。所以使用KVC時就要求模型的屬性必須喝字典的key值一一對應。

需求二:如果我們只想使用字典中的部分值呢?一個大字典,裡面有好幾十個key,難道我們還要在模型中根據key值定義幾十個屬性麽?當然我們程式猿都是很懶的,肯定不會定義這麼多key值的,此時我們只需重寫KVC的以下方法就行了:        

3.setValue(value: AnyObject?, forUndefinedKey key: String)

*這個方法會幫我們過濾我們沒有的key值,值執行 setValuesForKeysWithDictionary(dict)時,當監測出我們沒有字典中key值所對應的屬性時就會調用這個方法。                           

 *重寫時裡面不需要寫任何代碼,如果想列印哪些key值我們沒有時就可以在裡面列印。

需求三:我們知道很多字典中都有“id”這個key值。而“id”在我們iOS中是個數據類型,顯然不能將“id”當作模型屬性名稱去定義。此時我們只需要隨意定義一個屬性名去保存“id”,當然為了更已讀、嚴謹一些,我們一般還是定義為“ID”最為恰當。而我們知道要使用KVC就要key值和模型名一一對應,但是我們就是想要獲取“id”。此時需要將“需求一”和“需求二”結合起來看了。我們在獲取“id”時,直接使用傳入的字典賦值:(此時我們新添一個屬性“ID”)

eg :self.ID = dict[“id”]

*當這樣賦值之後就取出”id “所對應的value了。

但是我們還要獲取其他的value呢,此時在使用 setValuesForKeysWithDictionary(dict)完成其他屬性的賦值。當然也需要重寫setValue(value: AnyObject?, forUndefinedKey key: String)方法,因為字典中並有“ID”這個key值(字典中是“id”,“ID”是模型新定義的屬性)。完整代碼如下 :

swift:

override init() {

     super.init()

     self.ID = dict[@"id”];

     setValuesForKeysWithDictionary(dict)

}    

override func setValue(value: AnyObject?, forUndefinedKey key: String) { }

OC:

+ (instancetype) testWithDict:(NSDictionary *)dict{

    

    TEST *test = [[TEST alloc]init];

    

    test.ID = dict[@"id"];

    

    [test setValuesForKeysWithDictionary:dict];

    

    return test;

}

- (void)setValue:(id)value forUndefinedKey:(NSString *)key{

}

*註意當在對象方法使用KVC時一定要先super.init,因為要首先保證有一個對象存在,這樣才能訪問這個對象的屬性。

*註意在使用對象方法時,命名方法名時“With”中的“W”必須大寫,否則無法完成super.init

eg:- (instancetype) initWithDict:(NSDictionary *)dict

補充:KVC強大不僅僅只在於給模型賦值,KVC還可給只讀 屬性賦值,改變私有屬性。比如UITabBarController中tabBar是只讀屬性,用一般的賦值時無法給只讀屬性賦值的,但是通過

setValue(value,forKey:”屬性名”)

eg:setValue(value,forKey:“tabBar”)

總結:KVC是Set Value Coding的簡稱,它是一種直接通過字元串的名字(key)來訪問類屬性的機制。而不是通過Setter(設置器)和Getter(讀取器)。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.tableView隱藏滾動條 2.關於屬性 使用assign: 對基礎數據類型 (NSInteger,CGFloat)和C數據類型(int, float, double, char, 等等) 使用copy: 對NSString 使用copy: 對NSString 使用retain(strong) ...
  • 一,效果圖。 二,代碼。 RootViewController.m ...
  • 1:iOS 使用NJKWebViewProgress做webview進度條 2:解決輸入框UITextField關於拼音或部首被當作內容響應 這裡主要使用了兩個知識: 輸入法輸入時,拼音字母或者筆畫處於選中狀態,可以使用 markedTextRange 獲取到 普通輸入,以及將輸入法的待選字填入輸入 ...
  • 先把字元串轉換成時間NSDate 然後再把時間轉換成我們需要的時間格式的字元串 其中需要註意的是 EEE 和 MMM 所代表的含義 會隨著 NSDateForMatter 的 Locale 屬性的不同 而改變 當Locale 屬性為 ...
  • 最近在使用iOS的可變數組時出現了一個錯誤,報錯信息為: reason: '-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object' 字面的意思就是可變數組的方法發送給了一個不可變的對象。 聲明和初始 ...
  • 樣式和主題(Styles and Themes) 一個樣式(Style)是一個包含了指定樣子和格式的作用於視圖控制項(View)或者窗體(Window)屬性集合。一個style可以指定很多屬性,比如 高度,填充,字體顏色,字體尺寸,背景色等。一個Style在xml資源文件中定義,並且和在xml中指定的 ...
  • 源文件這裡有http://pan.baidu.com/s/1pLlDm6f UITableView與UISearchController搜索及上拉載入,下拉刷新 ...
  • Swift提供了類似C語言的流程式控制制結構,包括可以多次執行任務的for和while迴圈,基於特定條件選擇執行不同代碼分支的if和switch語句,還有控制流程跳轉到其他代碼的break和continue語句。 除了C裡面傳統的 for 條件遞增迴圈,Swift 還增加了 for-in 迴圈,用來更簡 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...