題型復(fù)現(xiàn)
你怎么理解OC這門語言?
OC的動態(tài)性表現(xiàn)在那些方面狼荞?
他有什么優(yōu)缺點(diǎn)呢辽装?
Why Objective-C
我們都知道Objective-C是喬老幫主帶著NexTSTEP回歸蘋果后為蘋果公司注入的新生力量,也正是這一股新生力量將蘋果推向了高峰相味,不管是在PC領(lǐng)域還是在移動設(shè)備領(lǐng)域如迟。那么,選擇Objective-C的理由又是什么呢攻走?
我們也可以參看官檔是怎么描述理由的殷勘,這里我小作翻譯而已。
選擇OC的原因很多昔搂。首先玲销,他是一種面向?qū)ο蟮恼Z言。打包在Cocoa框架中的功能只能通過面向?qū)ο蟮募夹g(shù)來使用摘符。其次贤斜,由于OC是標(biāo)準(zhǔn)ANSI Cc的擴(kuò)展策吠,所以現(xiàn)有的C程序可以得到OC框架的良好支持。因?yàn)镺bjective-C包含C瘩绒,所以在Objective-C中工作時可以獲得C的所有好處猴抹。你可以選擇何時以面向?qū)ο蟮姆绞綀?zhí)行某些操作(例如定義新類)以及何時堅持使用面向過程編程(定義結(jié)構(gòu)和某些函數(shù)而不是類)。
而且锁荔,OC是一門基本簡單的語言蟀给。他語法小巧,明確阳堕,同時更易于學(xué)習(xí)跋理。面向?qū)ο缶幊掏蚱渥允〉男g(shù)語和對抽象的強(qiáng)調(diào),使得新的學(xué)習(xí)者的學(xué)習(xí)曲線更加陡峭恬总。但像OC這樣組織良好的語言對于成為一名熟練的面向?qū)ο箝_發(fā)者意味著更少的困難前普。
和其他基于C的面向?qū)ο笳Z言相比,OC非常動態(tài)化壹堰。編譯器忽略了大量有關(guān)對象本身的處理拭卿,以便他們在運(yùn)行時再進(jìn)行處理。這樣在編譯器做的很多事情就都推遲到了運(yùn)行時贱纠。動態(tài)特性賦予了OC不同尋常的靈活性和強(qiáng)大的功能峻厚。例如,它產(chǎn)生的兩個其他面向?qū)ο笳Z言都沒有的好處:
其一是OC支持開放式的動態(tài)綁定并巍,這種風(fēng)格可以容納交互式用戶界面的簡單架構(gòu)。消息不一定受限于接受類甚至是方法名稱换途,因而軟件框架允許你在運(yùn)行時選擇某些設(shè)計上的自由懊渡。
其二,動態(tài)能夠構(gòu)建復(fù)雜的開發(fā)工具军拟。運(yùn)行時的接口提供有關(guān)正在運(yùn)行的應(yīng)用程序相關(guān)信息的訪問剃执,因而使對監(jiān)控程序的開發(fā)成為可能,以及其他一些干預(yù)和揭示底層結(jié)構(gòu)和活動的工具懈息。
上面摘自官檔肾档,我想這些已經(jīng)足以作為我們回答第一個問題的基礎(chǔ)。
動態(tài)性
OC是一門動態(tài)語言辫继,上面也略有提到他的動態(tài)性怒见。OC的動態(tài)性主要變現(xiàn)在三個方面。
1.動態(tài)類型(Dynamic Typing)
動態(tài)類型是指對象指針的動態(tài)性姑宽,體現(xiàn)就是OC里的id類型遣耍。我們知道id類型可以指向任意類型的OC對象,它具體指向什么類型是在運(yùn)行時確定的炮车。
最司空見慣的應(yīng)用就是Delegate的實(shí)現(xiàn)舵变,我們并不知道將來遵循當(dāng)前協(xié)議的是哪個類酣溃,所以在聲明delegate的時候往往使用id作為它的的類型。
但是纪隙,我們能用靜態(tài)類型還是要盡量使用靜態(tài)類型赊豌。畢竟這樣,編譯的時候編譯器能對代碼做類型檢查绵咱。
2.動態(tài)綁定(Dynamic Binding)
動態(tài)綁定呢碘饼,主要是指對象的方法和成員變量在運(yùn)行時才會得到唯一確定。例如我們熟悉的Java麸拄,某個對象方法和成員變量在編譯的時候就得到了唯一確定派昧,之后就不能做出改變。而OC呢拢切,在編譯之后還是可以動態(tài)新增成員變量或方法或者改變某些方法的執(zhí)行邏輯蒂萎。動態(tài)綁定就是辣么神奇。
首先看成員變量的動態(tài)性淮椰,就是指我們在運(yùn)行時可以為對象動態(tài)地新增成員變量五慈。當(dāng)然這個情況必須發(fā)生在objc_allocateClassPair之后objc_registClassPair之前。
動態(tài)添加方法的時機(jī)和條件同上主穗。
這里需要重點(diǎn)理解的是動態(tài)地改變方法執(zhí)行的邏輯泻拦。這里就有必要談?wù)凮C方法的本質(zhì)其實(shí)是消息的傳遞,OC中所有的方法調(diào)用在底層都會走消息傳遞objc_msgSend函數(shù)忽媒。所謂改變方法執(zhí)行的邏輯争拐,主要體現(xiàn)在三點(diǎn):
- 1.動態(tài)地交換原有方法
- 2.消息轉(zhuǎn)發(fā)
- 3.unrecongized selector的無crash處理
這三點(diǎn)這里暫且提及一下,以后的篇章會詳述晦雨。這里只是用以說明OC的動態(tài)綁定特性架曹。
3.動態(tài)加載(Dynamic Loading)
動態(tài)加載主要是指資源的動態(tài)加載,我們都知道iOS開發(fā)中圖片的類型有@1x, @2x, @3x闹瞧,程序使用圖片會根據(jù)當(dāng)前的設(shè)備自動加載對應(yīng)的圖片類型绑雄。
OC優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 1.動態(tài)特性
- 2.兼容C/C++
- 3.有Cateogory等擴(kuò)展
- 4.支持繼承
缺點(diǎn)
- 1.不支持命名空間(可以添加前綴來解決該問題)
- 2.不支持多繼承(NSProxy+消息轉(zhuǎn)發(fā)可以模擬實(shí)現(xiàn)多繼承)
- 3.不支持運(yùn)算符重載
- 4.很多編譯時優(yōu)化不支持,例如內(nèi)聯(lián)函數(shù)
擴(kuò)展:編程語言的分類
我們知道OC是一門動態(tài)語言奥邮。那么什么又是動態(tài)語言呢万牺?與之對應(yīng)的靜態(tài)語言又是什么呢?
動態(tài)語言是指數(shù)據(jù)類型的檢查是在運(yùn)行時做的洽腺。典型代表OC脚粟,Python,Ruby等蘸朋。
靜態(tài)語言是指數(shù)據(jù)類型的檢查是在編譯時做的珊楼。典型代表C++,Java度液,C#等厕宗。
另外画舌,編程語言還可以分為編譯語言,解釋語言和混合語言(相對于編譯型和解釋型)已慢。
編譯語言是先將源代碼編譯生機(jī)器指令曲聂,再由機(jī)器運(yùn)行機(jī)器碼。典型代表OC佑惠,C/C++朋腋,Swift等。
解釋語言是先將源代碼翻譯成中間代碼膜楷,再由解釋器對其解釋運(yùn)行旭咽。典型代表JavaScript,Python赌厅,Php等穷绵。
混合語言整合以上兩種類型,取其精華棄其糟粕特愿。典型代表Java仲墨,C#等。
其實(shí)之外揍障,按別的角度又能分為強(qiáng)類型定義語言和弱類型定義語言目养。
強(qiáng)類型定義語言是指數(shù)據(jù)類型的定義有嚴(yán)格的區(qū)分。一旦某個變量被定義為某種數(shù)據(jù)類型毒嫡,如果不經(jīng)過強(qiáng)制轉(zhuǎn)換那么他永遠(yuǎn)就是這個類型了癌蚁。他是類型安全的(編譯器會做檢查)。典型代表Java兜畸,Python等努释。
弱類型定義語言是指變量定義時數(shù)據(jù)類型可以被忽略,在賦值的時候被確定賦予哪種數(shù)據(jù)類型膳叨。他是類型不安全的(編譯器不做檢查)洽洁。典型代表JavaScript痘系,Php等菲嘴。
以上幾種對語言的分類只是從不同角度進(jìn)行的,跨角度分類之間沒有必然聯(lián)系汰翠。
思考題
1.C是強(qiáng)還是弱類型龄坪?OC呢?
2.以下代碼編譯會報錯嗎复唤?如果不會健田,其中obj在編譯和運(yùn)行時分別是什么類型?為什么NSString *obj =[ [NSData alloc] init ];
3.instancetype和id類型有什么區(qū)別佛纫?
4.OC項(xiàng)目怎么引用C代碼妓局?C++呢总放?
--------------------------------------------------------------20190526午后
我們所寫的代碼
所選擇的態(tài)度
以及所投入的時間和經(jīng)歷
都將成為通向黃金程序猿的
墊腳石-----------------------------非著名八線互聯(lián)網(wǎng)九流程序猿 chaors