帶大家學習Object-C Runtime錦集:property_getAttributes() 與 C++ typeid()

原文鏈接:https://abson.github.io/2016/10/31/typeid/

在逐漸開發(fā) iOS 當中,不少人都聽說過了 Runtime 運行時了,這個東西很多人都稱它為一個黑魔法,它不僅擁有著神秘的效用,而且這也成為標識 iOS 領域的分水嶺了,但是它是否真的很難呢?博主認為,很多事情,必須真正去嘗試了,動手了去做了,等回過頭來,也只是那么回事而已,所以別怕動手、思考。

在 Object-C 的 Runtime 當中,充當重要角色的property_getAttributes() 有著必不可少的地位 ,那什么是 property_getAttributes() 呢?

property_getAttributes: runtime 頭文件中這個 C 語言方法了 ,其作用就是用來獲取屬性的真實類型。

但是近期研究C++中,發(fā)現(xiàn)了一個有趣的事情,就是C++中擁有的Rumtime,自然就發(fā)現(xiàn)了 typeid 這個有趣的事情了,什么是 typeid 呢?

typeid: 為RTTI提供的運算符,它允許程序像表達式提問:你的對象是什么類型

那么我們就會想, property_getAttributes() 究竟跟 typeid 是否存在什么聯(lián)系呢?
答案是當然存在聯(lián)系了,以下文章內(nèi)容就圍繞著這個主題展開。


首先我們看看 property_getAttributes() 的使用方式和其作用
以下是個例子:

首先創(chuàng)建一個 Object-C 的測試例子類

@interface RunTimeTestObj : NSObject

@property (nonatomic, assign) int num;

@end

@implementation RunTimeTestObj

@end

然后我們使用熟悉的 runtime 方法來獲取這個測試類中的屬性,并識別其類型。( 這些內(nèi)容就是我們做 模型->字典 或 字典->模型 所用到的基礎 )


unsigned int outCount = 0;
objc_property_t* propertys = class_copyPropertyList([RunTimeTestObj class], &outCount);
for (unsigned i = 0; i < outCount; i++) {
    objc_property_t property = propertys[i];
    assert(property != nil);
    const char* name = property_getName(property);
    NSLog(@"name: %s", name);

    NSString* attrs = @(property_getAttributes(property));
    NSLog(@"code: %@", attrs);
}

上面例子輸出

name: num
attrs: Ti,N,V_num

上面輸出我們可以看出,name 自然是這個屬性的名稱了,但是 attrs: Ti,N,V_num 這串字符串又是什么呢?
我來為大家解析一下:
通過閱讀蘋果官方文檔可以看出

T: 在大寫 T 后面是放的是該屬性的數(shù)據(jù)類型
V: 在大寫 V 后面放的是該屬性的變量名稱(因為我們知道 @property 實際上只是為我們編寫好了 getter 和 setter 方法,并創(chuàng)建一個以下劃線開頭的變量)

輸出中看出,T后面放的是 i,那么 i 又是什么類型呢?
然后帶著這個問題,我找到了一張圖


是不是過于復雜了,不怕,等下博主為你們簡化一下,現(xiàn)在通過圖我們可以理解為 i 類型, 就是 int 類型

但是 N 又代表什么呢?
然后帶著這個問題,我找到了一張圖!

由圖片我們可以清晰的看到,N代表的是屬性的非原子屬性 nonatomic 的標識,當然我們加其他不同的標識也會有不同的字符,具體怎么樣,請看圖呀!

以上就是 property_getAttributes() 這個方法給到我們的信息了。

以下內(nèi)容是 C++ 相同內(nèi)容的對比了,沒有興趣的看官可以略過,直接看最后


那么C++ 中的typeid()能給到我們什么呢?我要說的是,runtime 技術(shù)都一樣,OC 只是高級語言,typeid 實際上就是 property_getAttributes() 所使用的技術(shù),我們再用實際例子看一看。

int p = 42;
double q = 43.f;
std::cout << typeid(p).name()<< "  " << typeid(q).name() << "\n";

很顯然,大家都知道結(jié)果輸出: i d
這是跟 Object-C 中一樣的套路呀,由此看出,runtime 技術(shù)都一樣,理解好了,走到那里都不怕。

最后我為大家附上 OC 中總結(jié) property_getAttributes() 得出的類型

NSString *const TypeInt = @"i"; 整數(shù)類型
NSString *const TypeShort = @"s"; 雙字節(jié)類型
NSString *const TypeFloat = @"f"; float 浮點型
NSString *const TypeDouble = @"d"; double 雙精度浮點型
NSString *const TypeLong = @"l"; long 長整型
NSString *const TypeLongLong = @"q";
NSString *const TypeChar = @"c"; char 單字節(jié)類型
NSString *const TypeBOOL1 = @"c"; bool 類型
NSString *const TypeBOOL2 = @"b"; bool 類型
NSString const TypePointer = @""; 指針類型
NSString *const TypeIvar = @"^{objc_ivar=}";
NSString *const TypeMethod = @"^{objc_method=}"; oc 方法類型
NSString *const TypeBlock = @"@?"; oc 閉包類型
NSString *const TypeClass = @"#"; oc class 類類型
NSString *const TypeSEL = @":"; oc slector 觸發(fā)器方法類型
NSString *const TypeId = @"@"; oc 泛型id類型

最后說上一句,以上不管是 property_getAttributes() 還是 typeid() 得出的這些標識字符,只是在 XCode 的 LLVM 編譯器上得出的字符標識,不同的編譯器的標識不一定相同喔。

參考資料:
蘋果官方手冊:
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容