每次聽(tīng)到“動(dòng)態(tài)語(yǔ)言”就會(huì)思考一次這個(gè)問(wèn)題包斑,OC
為什么是動(dòng)態(tài)語(yǔ)言?不同時(shí)期有不s同的理解件蚕。
最開(kāi)始的理解是盟迟,在運(yùn)行時(shí)才去調(diào)用特定的方法(OC
的消息轉(zhuǎn)發(fā)機(jī)制屬于動(dòng)態(tài)性,并不是多態(tài))踱承,編譯時(shí)并不確定將來(lái)運(yùn)行的時(shí)候調(diào)用什么方法倡缠。但是這個(gè)不就是面向?qū)ο蟮亩鄳B(tài)性嗎?一般的面相對(duì)象的語(yǔ)言都會(huì)有多態(tài)性茎活,例如java
昙沦,有多態(tài)性,但不是動(dòng)態(tài)語(yǔ)言载荔。
對(duì)于iOS
開(kāi)發(fā)人員來(lái)說(shuō)盾饮,除了OC
語(yǔ)言,其他的語(yǔ)言接觸的很少懒熙,更不會(huì)深入理解丘损,所以,不會(huì)有兩種語(yǔ)言的對(duì)比工扎,對(duì)于其他語(yǔ)言的了解徘钥,也只是了解一點(diǎn)皮毛,包括我肢娘。這個(gè)是搞iOS
呈础,或只搞一個(gè)平臺(tái)帶來(lái)的弊病舆驶。所以,如果只專(zhuān)注在一個(gè)平臺(tái)而钞,更具體點(diǎn)沙廉,專(zhuān)注于一種語(yǔ)言,那么臼节,對(duì)很多概念是無(wú)法理解的撬陵。
在我們需要具備其他一門(mén)語(yǔ)言的時(shí)候,swift
來(lái)了官疲,恰巧swift
又是一個(gè)靜態(tài)語(yǔ)言袱结,這樣,我們iOS
開(kāi)發(fā)者途凫,可以同時(shí)理解動(dòng)態(tài)語(yǔ)言和靜態(tài)語(yǔ)言了垢夹。
百度百科里關(guān)于動(dòng)態(tài)語(yǔ)言的定義
動(dòng)態(tài)語(yǔ)言,是指程序在運(yùn)行時(shí)可以改變其結(jié)構(gòu):新的函數(shù)可以被引進(jìn)维费,已有的函數(shù)可以被刪除等在結(jié)構(gòu)上的變化果元,類(lèi)型的檢查是在運(yùn)行時(shí)做的,優(yōu)點(diǎn)為方便閱讀犀盟,清晰明了而晒,缺點(diǎn)為不方便調(diào)試。
也就是阅畴,在程序運(yùn)行后倡怎,還可以添加新的函數(shù),或者刪除已有的函數(shù)贱枣,或者添加新的屬性监署,或者刪除已有的屬性,總之纽哥,就是可以修改你之前寫(xiě)好的代碼钠乏。例如,我定義了一個(gè)Person
類(lèi)春塌,代碼里只寫(xiě)了一個(gè)屬性name
晓避,但是,我可以在別的地方做些操作(寫(xiě)些代碼)只壳,給這個(gè)Person
類(lèi)俏拱,添加一個(gè)age
屬性,加一個(gè)eat
方法等等吕世。
我們做的操作是什么呢彰触?其實(shí)就相當(dāng)于你改了Person
類(lèi)的代碼,加上了age
屬性命辖,加上了eat
方法况毅。
也就是定義里說(shuō)的,
動(dòng)態(tài)語(yǔ)言尔艇,是指程序在運(yùn)行時(shí)可以改變其結(jié)構(gòu)尔许。
我們把原本只有一個(gè)name屬性的Person類(lèi)改的面目全非了。
我們都知道终娃,我們?cè)趺崔k到添加屬性和方法呢味廊?這個(gè)就是我們iOS
開(kāi)發(fā)者非常熟悉的runtime
。所以棠耕,我們說(shuō)余佛,OC
的動(dòng)態(tài)性是runtime
支持的。沒(méi)有runtime
窍荧,就不具備在運(yùn)行時(shí)修改代碼的能力辉巡。
runtime
的確是個(gè)偉大的特性,長(zhǎng)久以來(lái)都是iOS
程序員引以為傲的蕊退,但是swift
卻去掉了動(dòng)態(tài)性郊楣,原生并不支持runtime
。runtime
的特性在很多場(chǎng)景下都是最佳的解決方案瓤荔,所以净蚤,swift
沒(méi)有runtime
特性,的確讓人很不舒服输硝。
swift
可以通過(guò)兼容OC
來(lái)使用runtime
特性今瀑,但始終不是swift
的特性。
runtime
特性的確有很多的弊端点把,例如執(zhí)行速度上橘荠,肯定是靜態(tài)語(yǔ)言更快。但是動(dòng)態(tài)語(yǔ)言?xún)?yōu)點(diǎn)又顯然超過(guò)了弊端愉粤,所以砾医,在不久的將來(lái)swift
一定會(huì)加入runtime
特性,當(dāng)然衣厘,到時(shí)可能有一個(gè)新名字如蚜,未必還是叫runtime
。
runtime
在這里我們可以看作一個(gè)庫(kù)影暴,像其他庫(kù)一樣错邦,這個(gè)庫(kù)提供了一些API
,讓我們來(lái)實(shí)現(xiàn)添加方法型宙,刪除方法撬呢,交換方法等等。這個(gè)庫(kù)真正做了什么呢妆兑?是不是真的在運(yùn)行的時(shí)候去把我們寫(xiě)好的代碼改掉呢魂拦?例如添加一個(gè)方法毛仪,是不是真的在我們的代碼下面再寫(xiě)一個(gè)我們添加的方法呢?我們知道另外一件事芯勘,就是ARC
的實(shí)現(xiàn)機(jī)制箱靴,ARC并不是垃圾回收機(jī)制,而是荷愕,在編譯的時(shí)候衡怀,系統(tǒng)真的會(huì)給我們加上代碼(release
,retain
安疗,autorelease
等)抛杨。那runtime
是不是呢?顯然不是荐类,runtime
是在運(yùn)行的時(shí)候起作用的怖现,那個(gè)時(shí)候,代碼已經(jīng)完成了編譯掉冶,怎么還能改代碼呢真竖?所以,真正的改代碼只能發(fā)生在編譯前厌小,編譯之后就沒(méi)有辦法改代碼了恢共。
我們知道,OC
里有很多庫(kù)都是C/C++
實(shí)現(xiàn)的璧亚,包括runtime
庫(kù)讨韭,為什么是C/C++
實(shí)現(xiàn)?因?yàn)樗械?code>OC在編譯之前都會(huì)轉(zhuǎn)為C/C++
代碼癣蟋,也就是透硝,OC
不過(guò)是在C/C++
基礎(chǔ)上實(shí)現(xiàn)的一個(gè)語(yǔ)言,瞬間不那么高大上了疯搅。
OC
里的類(lèi)濒生,數(shù)組,各種結(jié)構(gòu)幔欧,各種邏輯罪治,最終都是C\C++
實(shí)現(xiàn)。例如礁蔗,我們要在OC
類(lèi)里添加一個(gè)方法觉义。在C++
層面是,OC
方法會(huì)轉(zhuǎn)為函數(shù)指針浴井,有一個(gè)數(shù)組存放這些函數(shù)指針晒骇,添加一個(gè)方法就是在這個(gè)數(shù)組里,再添加一個(gè)函數(shù)指針。在OC
看來(lái)洪囤,你給這個(gè)類(lèi)添加了一個(gè)方法徒坡。在C++
看來(lái),你不過(guò)是在數(shù)組里添加了一個(gè)元素箍鼓,并沒(méi)有什么奇怪的崭参。