YYModel 原始碼歷險記:關於變數型別和編碼

發表於2016-05-30

1. 變數

要說到變數,得先在這裡補充一個知識。每當我們定義一個類的時候,在宣告property時,總會帶上一些修飾詞,比如記憶體管理,是否原子性等,還需要帶上這個變數的資料型別,而這一些的宣告都是附帶在這個變數的屬性裡的,我們稱為property.Attributes,我們試著去獲取一個類裡變數的attributes看看裡面究竟帶有一些什麼

  1. 首先我們宣告一個Person類,在裡面宣告瞭三個引數,有基礎資料型別和系統的NSString型別還有自定義的Dog型別,並且我們宣告一個方法獲取到屬性的attributes並用字典的形式返回

2.在Person的實現中,我們通過runtime來獲取到值的屬性

3.當我們呼叫allProperties並且列印出這個返回的字典時 我們會得到如下的內容:

大喊一聲什麼鬼,什麼i什麼N什麼C,這是什麼東西,別急別急,我們來看一個東西,要理解這些符號就要先了解蘋果定義的Type Encodings也就是型別編碼,傳送門:蘋果官方文件官方文件2在這個文件中,蘋果對每一個變數的型別進行了編碼,對方法的型別也進行了編碼,於是我們獲取到變數的attributes時,就是經過編譯器編碼後得到的屬性。
我們參試著來看懂一個編碼的型別

dog = “T@”Dog”,&,N,V_dog”;

首先這個T@”Dog” 就是指這個變數是Dog型別,&代表的是retain的在ARC狀態下也就是strong型別,N表示的是是nonatomic的,V_dog表示這個變數的名字是dog,我們再來看一下我們的宣告,是不是覺得其實並不是那麼難看懂呢?具體需要再深入瞭解的話請查閱官方文件,這裡就不再進行贅述:

YYModel 原始碼歷險記:關於變數型別和編碼

2. YYClassInfo 中的EncodingType

2.1 列舉變數型別

開啟YYClassInfo我們發現在檔案的開頭定義了一個列舉型別,這個列舉型別大致分成了三個部分

接下來我們看一下在YYModel裡的具體實現

這裡有個地方可能不太能一下子理解就是為什麼定義了三個Mask,分別是
YYEncodingTypeMask
YYEncodingTypeQualifierMask
YYEncodingTypePropertyMask

在列舉裡,我們可以看到YY把這個列舉型別分為三類,二進位制中,在第八位的時候,定義為變數的型別,第8~16位的時候定義為方法的attributes,第16~24位定義為屬性的attributes型別,這樣我們也就很好理解為什麼要定義三個Mask了,直接可以通過列舉值&對應的mask找到它對應的部分是哪個值,這樣是為了區分不同部分的值,我們嘗試一下自己舉個例子:

然後我們定義一個變數擁有Type1 Qualifire2的屬性,然後分別想要取出它們Type和Qualifire的型別

列印的結果:

是不是跟我們預期一樣呢?YYModel用了不同的Mask來取得不同的type的值

2.2 獲取型別的方法

這裡比較容易理解直接上程式碼註釋

最後

在中午休息的時候抽空看了一下原始碼,希望明天能分享多一些,關於runtime的部分推薦一篇文章看完基本對runtime就瞭解了

Objective-C Runtime 1小時入門教程

相關文章