當時學習Object C的時被人鄙視了一頓,說使用.NET的思想來學Object C就是狗屎;不過也挺感謝這位仁兄的,這讓我學習的時候更加的謹慎。今天的學習筆記主要記錄Object C中的動态類型相關内容。
首先還是和.NET先對比一下,.NET中存在一個關鍵字var ,這個估計用過.NET的都知道,除非沒有接觸過3.0以上版本的。在.NET中能夠使用var來聲明任何類型的局部變量,負責告訴編譯器,該變量需要根據初始化表達式來推斷變量的類型,而且隻能是局部變量.但是這裡要注意的時var 并不是一個新的類型,隻是一個關鍵字而已,在定義參數和傳回值的時候都不能使用var.
在.net中還有一個類型dynamic,表示變量的類型在運作時決定,也就是在運作此代碼的時候才去校驗類型是否符合等,如果類型不符則會抛出異常。而var則會在編譯的過程就能夠發現類型是否準确。
在這裡我們要說Object C中的id類型 和 var 以及 dynamic 有什麼差別?
一. Object C中的id類型
在Objective-C 中,id 類型是一個獨特的資料類型。在概念上可以轉換為任何資料類型。換句話說,id 類型的變量可以存放任何資料類型的對象。在内部處理上,這種類型被定義為指向對象的指針,實際上是一個指向這種對象的執行個體變量的指針。
先看一段代碼了解一下id類型的時候:
以上代碼分别用建立了兩個類Student 和 Person的執行個體,類型都是使用的id,并且調用了其相應的方法,成功運作。
二. 動态判斷
在Object C中如何判斷某個類執行個體是否是某個類的子類,某個類中是否包含某個方法。這個要求似乎和.NET中的反射有點類似,的确在Object中同樣提供了類似的方法來動态判斷。
我們先定義一個父類:

Person 類
然後定義一個子類,用于繼承Person類。

Student 類
Student類繼承了Person類,說明Student類擁有了Person類的所有方法和屬性
(1) isMemberOfClass 用于判斷是否是某個類的執行個體
上面的代碼 flag1 為yes,而flag2為no,說明stu是Student類的執行個體,Student為Person的子類,但是不能判斷為Person的執行個體。
(2) isKindOfClass 判斷是否為某個類的執行個體或者某個類子類的執行個體
因為Student是Person的子類,是以上面flag1,flag2 的都為YES
(3) respondsToSelector 用于判斷某個類型或者對象是否有能力回應(調用)指定的方法

respondsToSelector 測試代碼
上面的代碼測試輸出結果如下:
第一個和第二個方法的調用都傳回1,說明其有能力回應(調用)方法eat, 關鍵看第三個和第四個方法的調用,傳回0,1 說明執行個體和對象的調用是不一樣的,而Info方法是一個全局方法 ,用 "+" 辨別的方法就是全局方法,相當于靜态方法。第3個方法是使用執行個體來調用的傳回0,說明對象執行個體是沒有能力調用靜态方法的。
(4) instancesRespondToSelector 用于判斷某個對象的執行個體是否有能力回應(調用)指定的方法
上面的測試代碼輸出結果如下:
第一個方法調用傳回1,說明Person的執行個體可以調用eat方法,第二個方法傳回0,說明Person的執行個體不可以調用Info方法。
三. 如何動态調用方法
上面已經說到了,任何一個對象的執行個體我們都可以使用id來指向其位址,這是一個動态的類型那麼如何調用其具體的方法。
使用performSelector 方法可以動态的調用其方法,如果是執行個體方法則調用的需要使用對象執行個體,而調用靜态方法這需要使用對象本身。
上面的辦法調用都是沒有參數的,那麼如何調用有輸入參數的方法呢?
使用withObject 來填充參數.但是這個方法的調用有點不足的地方,如果有多個參數輸入參數就有問題。 這個地方還沒有完全沒有弄清楚,有待後續研究。如果真的涉及到多個參數,那麼可以使用對象封裝好這些參數或者将參數存入一個集合中傳遞輸入。
四. 總結
這篇主要講到了動态類型id,以及其如何使用。還有關于類的動态判斷以及選擇器。但都隻是比較粗略的介紹了,後面的學習中繼續深入研究。
本文開頭的時候對比了.NET 中的var , dynamic 。 從上面的文章介紹,那麼Object C中的id 和 .NET中的哪個關鍵字比較像,個人的學習體會和dynamic比較類似,如有不對的正确的地方請高手斧正!
本文到此結束,請高手勿噴,菜鳥的學習需要鼓勵!