經常看到代碼中出現(xiàn)導入<objc/runtime.h>,但一直處于各種理由沒有詳細了解一下胜臊,今天在馬上要回學校答辯的時候仔細的研究了下Objc Runtime吞加。
首先裙犹,來了解一下什么是Objc Runtime?
Objective-C語言是一門動態(tài)語言衔憨,它將很多靜態(tài)語言在編譯和鏈接時期做的事放到了運行時來處理叶圃。這種動態(tài)語言的優(yōu)勢在于:我們寫代碼時能夠更具靈活性,如我們可以把消息轉發(fā)給我們想要的對象践图,或者隨意交換一個方法的實現(xiàn)等掺冠。這種特性意味著Objective-C不僅需要一個編譯器,還需要一個運行時系統(tǒng)來執(zhí)行編譯的代碼码党。對于Objective-C來說德崭,這個運行時系統(tǒng)就像一個操作系統(tǒng)一樣:它讓所有的工作可以正常的運行。這個運行時系統(tǒng)即Objc Runtime揖盘。Objc Runtime其實是一個Runtime庫眉厨,它基本上是用C和匯編寫的,這個庫使得C語言有了面向對象的能力兽狭。runtime的強大之處在于它能在運行時創(chuàng)建類和對象憾股。
Objective-C類是由Class類型來表示的,它實際上是一個指向objc_class結構體的指針椭符。它的定義如下:
typedef struct objc_class *Class;
因為現(xiàn)在的objc是2.0荔燎,所以上述的Class可以簡化為:
struct objc_class {
Class isa;
}
基本概念
對于現(xiàn)在絕大多數(shù)的64位系統(tǒng)而言,我們接觸到的都是ObjC2.0的modern runtime销钝。ObjC程序從3個層次來使用到runtime:
1.ObjC源碼
這說明了runtime是ObjC的基石有咨,你定義的類/方法/協(xié)議等等,最后都需要使用到runtime蒸健。其中座享,最重要的部分就是方法的messaging。
2.ObjC方法(Method)
絕大多數(shù)ObjC都繼承自NSObject似忧,他們都可以在運行的時候檢查屬于/繼承哪個類渣叛,某個對象是否有某個方法,是否實現(xiàn)了某個協(xié)議等等盯捌。這一部分是編程時淳衙,經常會使用到的。
3.ObjC函數(shù)(Function)
Runtime相關的頭文件在: /usr/include/objc中,我們可以使用其中定義的對象和函數(shù)箫攀。通常情況下肠牲,我們很少會使用到。但個別情況我們可能需要使用靴跛,比如swizzling缀雳。此外,這些純C的實現(xiàn)說明了我們可以用C來實現(xiàn)ObjC的方法梢睛。
Messaging
之前說過肥印,所有的ObjC方法最后都通過runtime實現(xiàn),這都是通過調用函數(shù)objc_msgSend. 也就是說諸如:
[receiver doSomething] 的調用最終都是展開調用objc_msgSend完成的绝葡。 在此之前深碱,先看下ObjC的class定義:
因為現(xiàn)在的objc是2.0,所以上述的Class可以簡化為:
struct objc_class {Class isa;}
Class只是一個包含了指向自身結構體的isa指針的結構體挤牛,雖然這個結構體具體的內容沒有找到定義莹痢,但是根據(jù)頭文件里的寫法我們可以猜測,它必定還包含父類墓赴,變量竞膳,方法,協(xié)議等信息(最新的runtime信息可以在opensource中查看)诫硕。
導入runtime后如何簡單使用:
objc_getAssociatedObject? 相當于iOS內部的get方法
OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)
OSX_AVAILABLE_STARTING(MAC_10_6, __IPHONE_3_1);
1.id object :? 關聯(lián)對象
2.const voidkey: 我們需要定義一個常量void類型的key
objc_setAssociatedObject? 相當于iOS的屬性的set方法
OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
OSX_AVAILABLE_STARTING(MAC_10_6, __IPHONE_3_1);
1.id object :被關聯(lián)的對象
2.const void *key? :char 類型的key
3.id value? :要被賦值的值
4.objc_AssociationPolicy policy :runtime內存管理有一下集幾種
OBJC_EXPORT void objc_removeAssociatedObjects(id object)
OSX_AVAILABLE_STARTING(MAC_10_6, __IPHONE_3_1);
id object: 移除關聯(lián)對象坦辟,用法不是很難,但是在使用中最好是合理使用章办,