- 引言
- 簡介
- 與Runtime交互
- Runtime術(shù)語
- 消息
- 動態(tài)方法解析
- 消息轉(zhuǎn)發(fā)
- 健壯的實例變量(Non Fragile ivars)
- Objective-C Associated Objects
- Method Swizzling
- 總結(jié)
引言
曾經(jīng)覺得Objc特別方便上手,面對Cocoa中大量的API,只知道簡單的查文檔和調(diào)用。還記得初學(xué)Objective-C時把[receiver message]當(dāng)成簡單的方法調(diào)用,而無視了"發(fā)送消息"這句話的深刻含義。其實[receiver message]會被編譯器轉(zhuǎn)化為:
objc_msgSend(receiver, selector)
如果消息含有參數(shù),則為:
objc_msgSend(receiver,selector,arg1,arg2,...)
如果消息的接受者能夠找到對應(yīng)的selector,那么就相當(dāng)于直接執(zhí)行了接受者這個對象的特定方法;否則,消息要么被轉(zhuǎn)發(fā),或是臨時向接收者動態(tài)添加這個selector對應(yīng)的實現(xiàn)內(nèi)容,要么就干脆玩完崩潰掉。
現(xiàn)在可以看出[receiver message]真的不是一個簡簡單單的方法調(diào)用悉盆。因為這只是在編譯階段確定了要向接受者發(fā)送message這條消息,而receive將要如何響應(yīng)這條消息,那就要看運行時發(fā)生的情況來決定了蜓谋。
Objective-C 的Runtime鑄就了它動態(tài)語言的特性,這些深層次的知識雖然平時寫代碼用的少一些,但是卻是每個Objc程序員要了解的嗜侮。
簡介
因為Objc是一門動態(tài)語言,所以它總是想辦法把一些決定工作從編譯連接推遲到運行時检号。也就是說只有編譯器是不夠的,還需要一個運行時系統(tǒng)(runtime system)來執(zhí)行編譯后的代碼熔号。這就是Objective-C Runtime系統(tǒng)存在的意義,它是整個Objc運行框架的一塊基石赴肚。
Runtime其實有兩個版本:"modern"和"legacy"素跺。我們現(xiàn)在用的Objective-C2.0采用的是現(xiàn)行(Modern)版的Runtime系統(tǒng),只能運行在iOS和OS X 10.5之后的64位程序中。而OS X較老的32位程序仍采用Objective-C 1中的(早期)Legacy版本的Runtime系統(tǒng)誉券。這兩個版本最大的區(qū)別在于當(dāng)你更改一個類的實例變量的布局時,在早期版本中你需要重新編譯它的子類,而現(xiàn)行版就不需要指厌。
Runtime基本是用C和匯編寫的,可見蘋果為了動態(tài)系統(tǒng)的高效而作出的努力。你可以在這里下到蘋果維護(hù)的開源代碼踊跟。蘋果和GNU各自維護(hù)一個開源的runtime版本,這兩個版本之間都在努力的保持一致踩验。
與Runtime交互
Objc從三種不同的層級上與Runtime系統(tǒng)進(jìn)行交互,分別是通過Objective-C源代碼,通過Foundation框架的NSObject類定義的方法,通過對runtime函數(shù)的直接調(diào)用。