Objective-C與C++呜魄、Java等面向?qū)ο笳Z言類似毙籽,不過很多方面還是有差別的步绸。如果你用過另外一種面向?qū)ο蟮恼Z言尝丐,那就能理解Objective-C所用的許多范式和模板显拜。但是語法上還是有陌生感。因為該語言使用了“消息結(jié)構(gòu)”而非“函數(shù)調(diào)用”爹袁。(Objective-C語言由Smalltalk演化而來远荠,后者是消息型語言的鼻祖)
// Objective-C
Object *obj = [Object new];
[obj performWith:parameter1 and:parameter2];
// C++
Object *obj = new Object;
obj->perform(parameter1, parameter2);
區(qū)別:消息結(jié)構(gòu)的語言,其運行時所執(zhí)行的代碼由運行環(huán)境來決定失息,而函數(shù)調(diào)用的語言譬淳,則由編譯器決定。如果示例代碼中調(diào)用的函數(shù)是多態(tài)的根时,那么在運行時要按照“虛方法表”來查找到底要執(zhí)行哪個函數(shù)實現(xiàn)瘦赫。但是采用消息結(jié)構(gòu)的語言,無論是否多態(tài)蛤迎,總是在運行期才會去查找所要執(zhí)行的方法确虱。事實上,編譯器甚至不關(guān)心接收消息的對象的什么類型替裆,接收消息的對象問題也要在運行時處理校辩,這個過程叫做“動態(tài)綁定”。
Objective-C的重要工作都由“運行期組件”來完成辆童,而不是“編譯器”宜咒。使用Objective-C的面向?qū)ο筇匦运璧娜繑?shù)據(jù)結(jié)構(gòu)及函數(shù)都是在“運行期組件”里面(全部內(nèi)存管理方法也在)“鸭“運行期組件”的本質(zhì)上就是一種和開發(fā)者所編代碼相連接的”動態(tài)庫“故黑,其代碼能把開發(fā)者編寫的所有程序粘合起來。這樣的話庭砍,只要更新”運行期組件“场晶,就能提升程序性能。但是在”編譯器“完成的語言怠缸,則需要重新編譯代碼诗轻,才可以提升性能。
Objective-C是C語言的“超集”揭北,C語言的所有功能在Objective-C中都適用扳炬。其中我們要理解C語言的內(nèi)存模型,這有助于我們理解Objective-C的內(nèi)存模型和“引用計數(shù)”機(jī)制的工作原理搔体。
Objective-C語言中的指針是用來指示對象的恨樟,聲明一個變量,令其指代某個對象:
NSString *someStr = @"The string";
聲明了一個名為:someStr的變量疚俱,類型是:NSString *厌杜,也就是說,此變量為指向NSString的指針(指針就是地址)计螺。所有的Objective-C都必須這樣聲明夯尽。因為對象所占內(nèi)存必須分配在“堆空間”,絕不能分配在“椀锹”上匙握。
someStr變量指向分配在堆里面的某塊內(nèi)存,其中含有一個NSString對象陈轿。如果再創(chuàng)建一個變量圈纺,讓它指向同一地址,那么并不拷貝改對象麦射,只是2個變量會同時指向此對象:
NSString *someStr = @"The string";
NSString *anotherStr = someStr;
只有一個NSString實例蛾娶,卻有2個變量指向此實例,類型都是NSString *潜秋。這說明“椈桌牛”里分配了2塊內(nèi)存,每塊的大小能存下一枚指針峻呛,且值是一樣的罗售,就是NSString實例的內(nèi)存地址。
分配在堆中的內(nèi)存必須直接管理钩述,分配在棧上的用于保存變量的內(nèi)存則會在其棧幀彈出時自動清理寨躁。Objective-C將堆內(nèi)存管理抽象出來了,不需要malloc和free來分配和釋放對象所占的內(nèi)存了牙勘。Objective-C運行期環(huán)境吧這部分工作抽象為一套“內(nèi)存管理框架”--“引用計數(shù)”职恳。
在Objective-C中,有時會遇到定義里沒有“*”的變量方面,它們可能會使用“椃徘眨空間”。這些變量保存的不是Objective-C對象葡幸。比如:CoreGraphics框架中的CGRect就是最筒。
struct CGRect {
CGPoint origin;
CGSize size;
}
typedef struct CGRect CGRect;
整個系統(tǒng)框架都在使用這樣的結(jié)構(gòu)體,因為如果改用Objective-C對象的話蔚叨,性能將會受到影響床蜘,因為創(chuàng)建對象需要額外的開銷,例如分配和釋放內(nèi)存等蔑水。如果需要保存int邢锯、float、double搀别、char等“非對象型”丹擎,那么使用像CGRect這樣的結(jié)構(gòu)體就足夠了。
要點:
1.Objective-C給C語言添加了面向?qū)ο蟮奶匦裕瞧涑倥唷bjective-C使用動態(tài)綁定的消息結(jié)構(gòu)再愈,也就說,在運行期才會去檢查對象類型护戳。接收一條消息之后翎冲,究竟應(yīng)該執(zhí)行什么代碼,由運行期環(huán)境決定媳荒,而不是編譯器抗悍。
2.理解C語言的核心概念有助于寫好Objective-C程序,尤其是掌握內(nèi)存模型與指針钳枕。