給你 C 語言,如何實現一個 Objective-C?java
一個OC的編程者的內功有多深厚,就是要看編程者能把 「給你 C 語言,如何實現一個 Objective-C?」 這個問題答到什麼程度。是的OC就是C的超集,而這是爲什麼,則要牽扯到一個歷史悠久的語言SmalkTalk.編程
Smalltalk 是世界上第二個面向對象的語言。(很惋惜因爲編譯速度慢的緣由,它最後仍是被拋棄),然而它的思想則對以後的編程語言有着超前的指導做用。編程語言
基本思想一:徹底的面向對象。萬事萬物都是對象,比Java還要完全的面向對象,包括數據常量也是對象。函數
基本思想二:一切行爲(也就是java中的方法),再也不理解爲方法調用,而是理解爲向一個對象發送消息,也就是向一個對象發送一條命令,這個消息命令也能夠帶參數。
而OC 的發明者 Brad Cox 和 Tom Love 在當時主流且高效的 C 語言基礎上,借鑑 Smalltalk 這兩個思想一想要搞出一個易用且輕量的 C 語言擴展,但 C 和 Smalltalk 的思想和語法格格不入,好比在 Smalltalk 中一切皆對象,一切調用都是發消息:學習
233 log
再好比用一個工廠方法來實例化一個對象:ui
p := Person name: 'sunnyxx' age: 26
在當時來看,一個具備面向對象功能的 C 語言真的是很是有吸引力,但必須得解決消息語法的轉換,因而乎他們開發了一個 Preprocessor,去解析 Smalltalk 風格的語法,再轉換成 C 語言的代碼,進而和其餘 C 代碼一塊兒編譯。這個過程和如今 JavaScript 裏的 CoffeeScript、JSX 很類似,構建一個 DSL,用轉化器轉化成原始語言的代碼。設計
然而如今問題來了, Smalltalk 語法裏面又是空格、又是冒號的,萬一遇到個什麼複雜嵌套調用,語法解析多難寫呀,因而乎他們想,既然什麼花括號 大括號都有了,那隻好把消息兩邊加個中括號吧 ,這樣 Parser 寫起來簡單多了呢對吧:code
[Person name:"sunnyxx" age: 26];
這就造就了 Objective-C 奇怪的中括號、冒號四不像語法,這怎麼看都是個臨時的方案,但在當時多是惟一方法,借用已有的 C 的編譯器比重造一個成本低多了,並且徹底兼容 C 語言。隨着這幾年 Apple 開發的火熱,Objective-C 愈來愈成爲 Apple 不爽的地方,先是恨透了在 GCC 上給 Objective-C 加支持,本身重建了個 Clang,後是乾脆從新發明了個 Swift 來完全代替,用 30 年的時間終於還完了這個技術債。對象
好的,雖然有了個 Preprocessor,但只能作到把 Smalltalk 風格的代碼分析並轉譯成 C,還須要解決兩個問題:ip
語言上實現一個 OOP 對象模型
將 Smalltalk 風格的 Message 機制轉換成 C 函數調用
對象模型的設計倒很省事,直接照搬 Smalltalk 的就行了:如 Class / Meta Class / Instance Method / Class Method 這些概念,還有一些關鍵字如 self / super / nil 等全都是 Smalltalk 的。這步轉換在 Preprocessing 過程當中就能夠完成,由於重寫後的 Class 就是原本來本的 C 語言的 Struct,只須要按 Smalltalk 中「類-元類」的模型設置好便可,無需額外的支持。
消息機制就不同了,要實現向一個 target ( class / instance ) 發送消息名 ( selector ) 動態尋找到函數實現地址 ( IMP ) 並調用的過程,還要處理消息向父類傳遞、消息轉發( Smalltalk 中叫 「Message-Not-Understood」)等,這些行爲沒法在 Preprocessing 或 Build Time 實現,須要提供若干 運行時 的 C 函數進行支持,全部這些函數打個包,便造成了最原始的 Runtime 。
因此最初的 Objective-C = C + Preprocessor + Runtime
這樣的的話,大概能夠把OC上全部的類理爲它們都是實例。而爲何喬布斯會選擇OC作開發語言,由於這自己就是在高級語言身上再封裝了一層的語言。則會讓開發者學習成本更低,更多開發者願意投身於iOS應用的開發。而如今的Swift 的想法也是如此,讓語言更簡單,讓編程更容易。推出workplace 這玩意來輔助也是如此。