前言:大四畢業(yè)季钉赁,找工作一不小心就從 Android 開(kāi)發(fā)工程師找成了 Mac 開(kāi)發(fā)工程師,所以開(kāi)發(fā)的主力語(yǔ)言也從 Java 轉(zhuǎn)變?yōu)?Objective-C(下文統(tǒng)一用 OC 表示)携茂,現(xiàn)在已經(jīng)學(xué)習(xí) OC 兩個(gè)來(lái)月了你踩,決定抽出時(shí)間,寫下這兩門語(yǔ)言的對(duì)比與理解讳苦,這個(gè)話題一看就感覺(jué)很有趣带膜,但因?yàn)?OC 學(xué)習(xí)時(shí)間不長(zhǎng),如有錯(cuò)誤鸳谜,請(qǐng)記得指出哈
歷史
1980年膝藕,Brad Cox 發(fā)明了新的編程語(yǔ)言 Objective-C,最初只是作為 C 語(yǔ)言的簡(jiǎn)單擴(kuò)展咐扭。
1995年芭挽,Sun 公司在 Sun world 會(huì)議上正式發(fā)布 Java 和 HotJava 瀏覽器。
從語(yǔ)言的歷史來(lái)看蝗肪,Java 語(yǔ)言的誕生相對(duì) OC 晚了十多年袜爪。這也導(dǎo)致了 Java 語(yǔ)言吸取了很多前期面向?qū)ο笳Z(yǔ)言優(yōu)點(diǎn),了解過(guò) Java 的同學(xué)大多知道 Java 是從 C++ 上面改變過(guò)來(lái)的薛闪。同時(shí)辛馆,規(guī)避了前期面向?qū)ο笳Z(yǔ)言的很多缺點(diǎn)。這也是造就了后面 Java 語(yǔ)言盛況空前的原因之一豁延。OC 的熱度完全是由基于 OC 編寫的熱門 iOS 應(yīng)用帶起來(lái)昙篙,但現(xiàn)在由于蘋果公司推出新語(yǔ)言 Swift,熱度有了明顯的下降术浪,除了舊項(xiàng)目可能因?yàn)樘鎿Q成本比較大還需要使用 OC 進(jìn)行開(kāi)發(fā)瓢对。
Bjarne 大神曰過(guò),編程語(yǔ)言就兩種胰苏,一種沒(méi)人用硕蛹,一種被人罵。Java 火所以被罵的很多,但不能說(shuō) Java 就真的差法焰。而 OC 以前沒(méi)人用就沒(méi)那么多人罵秧荆,但后來(lái)用的人多了,OC 也開(kāi)始被罵的很多
學(xué)習(xí)難度
OC 和 Java 對(duì)比來(lái)看的話埃仪,我認(rèn)為 OC 語(yǔ)言的難度要稍大一些乙濒,OC 語(yǔ)言自開(kāi)發(fā)出來(lái)以后,基本上一直都是蘋果公司在支持和完善÷羊龋現(xiàn)代OC語(yǔ)言在傳統(tǒng)面向?qū)ο笳Z(yǔ)言的基礎(chǔ)上增加很多特性颁股,例如:Category、Extension傻丝、ARC甘有、.語(yǔ)法來(lái)訪問(wèn)屬性的 getter/setter 方法等等。但網(wǎng)上的資料參差不齊葡缰,比如網(wǎng)上不同時(shí)間對(duì) @property 這一個(gè)屬性資料會(huì)有所偏差亏掀,這些都增加了學(xué)習(xí)成本。但最好學(xué)習(xí)的資料當(dāng)然是蘋果的官方文檔泛释。
而對(duì)于 Java 語(yǔ)言相對(duì)而言滤愕,學(xué)習(xí)成本是最低的,網(wǎng)上的資料很多怜校,而且每個(gè)版本語(yǔ)法差異基本可以忽略不計(jì)间影,不需要你懂得指針的概念,但懂得當(dāng)然更好韭畸。
故從學(xué)習(xí)難度的對(duì)比來(lái)看宇智,Java 語(yǔ)言的學(xué)習(xí)難度較低,OC 語(yǔ)言的學(xué)習(xí)難度較高胰丁,但這兩門語(yǔ)言都有一個(gè)特點(diǎn)随橘,就是特別啰嗦,但啰嗦也有明顯的好處锦庸,對(duì)于新手理解起來(lái)會(huì)更容易點(diǎn)机蔗。
語(yǔ)法
先貼下代碼對(duì)比下。
同樣定義一個(gè)關(guān)于人的類甘萧,并實(shí)現(xiàn)一個(gè)吃的方法萝嘁,語(yǔ)法如下:
Java
// Person.java
public class Person {
// 構(gòu)造器
public Person {
super(); // 調(diào)用父類構(gòu)造器
}
public void eat(String food) {
System.out.println("I eat the " + food);
}
}
// mian 方法調(diào)用的代碼內(nèi)容
Person p = new Person();
p.eat("apple"); // 此時(shí)輸出: I eat the apple
OC
// Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
- (void)eat:(NSString *)food;
@end
//Person.m
@implementation Person
- (instancetype)init {
self = [super init]; // 調(diào)用父類構(gòu)造器
if (self) {
// 自定義初始化屬性
}
return self;
}
- (void)eat:(NSString *)food {
NSLog(@"I eat the %@", food); // 此時(shí)輸出: I eat the apple
}
@end
// mian 方法調(diào)用的代碼內(nèi)容
Person *p = [[Person alloc] init];
[p eat:@"apple"];
類文件的組織
Java 為了更好地組織類,Java 提供了包機(jī)制扬卷,用于區(qū)別類名的命名空間牙言,這樣有利于屏蔽同類名的沖突。關(guān)于包怪得,由兩個(gè)關(guān)鍵字確定咱枉,一個(gè)是 package
卑硫,定義包的位置,一個(gè)是 import
蚕断,導(dǎo)入一個(gè)包的內(nèi)容欢伏。
而 OC 有 import
導(dǎo)入的概念,但沒(méi)有 package
這個(gè)區(qū)分類這種概念亿乳,所以它另辟新徑通過(guò)添加前綴來(lái)防止命名沖突硝拧,因此你會(huì)看到大量的以 NS 為前綴的類名、結(jié)構(gòu)體葛假、枚舉等障陶。而我們的類名應(yīng)該以三個(gè)大寫字母作為前綴(因?yàn)殡p字母前綴為 Apple 的類預(yù)留,避免以后蘋果突然要使用剛剛好跟你有沖突的雙字母桐款,蘋果爸爸就是霸道)咸这。
為什么 OC 中大量類選擇使用 NS 作為前綴呢夷恍,NeXTSTEP 是由 NeXT.Inc 所開(kāi)發(fā)的操作系統(tǒng)魔眨。NeXT 是已故蘋果電腦 CEO 喬布斯在 1985 年離開(kāi)蘋果電腦后所創(chuàng)立的公司。所以 "NS" 被作為 Fundation 中所有成員的前綴
創(chuàng)建對(duì)象
從上面看酿雪,Java 創(chuàng)建對(duì)象遏暴,主要是通過(guò) new
操作,就會(huì)去調(diào)用構(gòu)造方法(其實(shí)Person p = new Person();
這句語(yǔ)句并不是個(gè)原子操作指黎,實(shí)際上在匯編層次分為三個(gè)步驟:分配實(shí)例分配內(nèi)存朋凉,執(zhí)行構(gòu)造函數(shù)內(nèi)容,把該內(nèi)存分配給變量)醋安。
而 OC 中分為兩步:申請(qǐng)分配內(nèi)存和初始化杂彭,即 alloc
和 init
。詳情如下:
-
alloc
: 負(fù)責(zé)創(chuàng)建對(duì)象吓揪,這個(gè)過(guò)程包括分配足夠的內(nèi)存來(lái)保存對(duì)象亲怠,寫入 isa 指針,初始化引用計(jì)數(shù)柠辞,以及重置所有實(shí)例變量团秽。將返回一個(gè)有效的未初始化的對(duì)象實(shí)例。 -
init
: 負(fù)責(zé)初始化對(duì)象叭首,這意味著使對(duì)象處于可用狀態(tài)习勤。這通常意味著為對(duì)象的實(shí)例變量賦予合理有用的值。
從上面觀看 OC 代碼可以了解到關(guān)于約定俗成的重要部分:
init
這個(gè)方法可以(并且應(yīng)該)通過(guò)返回 nil 來(lái)告訴調(diào)用者焙格,初始化失敗了图毕;因?yàn)槌跏蓟赡軙?huì)各種原因失敗,比如一個(gè)輸入的格式錯(cuò)誤了眷唉,或者另一個(gè)需要的對(duì)象初始化失敗了予颤,又或者給空對(duì)象發(fā)消息不會(huì) Crash 但就初始化失敗了损肛。這樣我們就能理解為什么總是需要調(diào)用self = [super init]
。如果你的父類說(shuō)初始化自己的時(shí)候失敗了荣瑟,那么你必須假定你正處于一個(gè)不穩(wěn)定的狀態(tài)治拿,因此在你的實(shí)現(xiàn)里不要繼續(xù)你自己的初始化并且也返回 nil。如果不這樣做笆焰,你可能會(huì)操作一個(gè)不可用的對(duì)象劫谅,它的行為是不可預(yù)測(cè)的,最終可能會(huì)導(dǎo)致你的程序崩潰嚷掠。
方法調(diào)用的設(shè)計(jì)
Java 語(yǔ)言使用點(diǎn)語(yǔ)法調(diào)用方法捏检,大多語(yǔ)言也是使用這樣的語(yǔ)法,很保守也很實(shí)在不皆,更容易被人接受贯城,也更容易理解。
OC 的方法調(diào)用在編程語(yǔ)言上屬于非常特別的存在霹娄,頗為前衛(wèi)能犯,使用中括號(hào)的方式實(shí)現(xiàn)方法的調(diào)用,這也導(dǎo)致了后來(lái)一批程序員不愿接觸這門語(yǔ)言犬耻,原因僅僅是因?yàn)檎Z(yǔ)法太過(guò)奇葩踩晶。同時(shí),OC 通常不把這個(gè)叫做方法調(diào)用枕磁,而稱之為給對(duì)象發(fā)送消息渡蜻。為什么叫消息發(fā)送,在下一點(diǎn)會(huì)著重介紹计济。
空對(duì)象調(diào)用方法
Java 中調(diào)用 null 對(duì)象的方法茸苇,會(huì)報(bào)臭名昭著的 NulllPointerException 空指針異常,但對(duì)于老手來(lái)說(shuō)這種問(wèn)題其實(shí)是最容易解決的問(wèn)題沦寂。
而 OC 中向 nil 發(fā)消息学密,程序是不會(huì)崩潰的。同時(shí)視方法返回值凑队,向 nil 發(fā)消息可能會(huì)返回 nil(返回值為對(duì)象)则果、0(返回值為一些基礎(chǔ)數(shù)據(jù)類型)或 0X0(返回值為id)等。
為什么會(huì)這樣呢漩氨?因?yàn)?OC 的函數(shù)調(diào)用底層實(shí)現(xiàn)都會(huì)轉(zhuǎn)換為一個(gè) C 語(yǔ)言實(shí)現(xiàn)的 objc_msgSend 函數(shù)進(jìn)行消息發(fā)送來(lái)實(shí)現(xiàn)的西壮,其中實(shí)現(xiàn)細(xì)節(jié)會(huì)通過(guò)判斷 self 是否有值來(lái)決定是否發(fā)送消息,如果 self 為 nil叫惊,那么 selector 也會(huì)為空款青,直接返回,所以不會(huì)出現(xiàn)問(wèn)題霍狰。當(dāng)然抡草,假如對(duì)一個(gè)野指針發(fā)送消息饰及,那么這個(gè)時(shí)候肯定是會(huì) crash 的,安全的做法是釋放后將對(duì)象重新置為 nil康震。這種事在 MRC 的情況下可能發(fā)生燎含。
接口特性
Java 和 OC 都有接口的概念,但 Java 的接口關(guān)鍵字是 interface
腿短,接口里面所有的方法都必須實(shí)現(xiàn)屏箍。
而 OC 中定義類的 @interface
和 Java 中的 interface
不是一回事,@protocol
(OC里面稱之為協(xié)議)和 Java 中的 interface
才是一回事橘忱,OC 協(xié)議里面的方法不一定要全部實(shí)現(xiàn)赴魁,可以通過(guò) @required
和 @optional
去選擇設(shè)置。
可能從接口的設(shè)計(jì)對(duì)比來(lái)看钝诚,OC 有可選和必選可能會(huì)稍微好一些颖御,但假如真的出現(xiàn)可選,可能也是抽象這個(gè)方面做得不夠好凝颇,其實(shí)往這個(gè)方向想潘拱,其實(shí)沒(méi)毛病,畢竟 OC 并不是完全的面向?qū)ο蟮恼Z(yǔ)言祈噪。
認(rèn)真觀察泽铛,protocol
其實(shí)并沒(méi)有大量地在 OC 的代碼中使用也沒(méi)有在社區(qū)中普及(指的是那種像 Java 程序員使用 interface
那樣來(lái)使用 protocol
的方式)。一個(gè)主要原因是大多數(shù)的 Apple 開(kāi)發(fā)的代碼沒(méi)有采用這種的方式辑鲤,而幾乎所有的開(kāi)發(fā)者都是遵從 Apple 的模式以及指南。Apple 幾乎只是在委托模式下使用 protocol杠茬。
.h
文件設(shè)計(jì)技巧Tips
- 對(duì)于使用協(xié)議月褥,像 delegate 相關(guān) protocol 的書寫不應(yīng)該在頭文件
@interface
中聲明,而應(yīng)該在類擴(kuò)展中聲明瓢喉;需要公開(kāi)由外部調(diào)用的協(xié)議宁赤,如<NSCopying>
則寫在.h
文件是正確的。- 內(nèi)部屬性栓票,實(shí)例變量和
IBoutlet
不應(yīng)該在.h
文件定義决左,這樣相當(dāng)于是把內(nèi)部實(shí)現(xiàn)暴露出去了- 調(diào)用者對(duì)
IBAction
同樣不需要 care,也不應(yīng)該在.h
文件定義
setter/getter 方法
Java 生成一個(gè)實(shí)體對(duì)象走贪,一般都會(huì)把屬性設(shè)置為私有佛猛,對(duì)外按需書寫提供 setter/getter 方法操作對(duì)應(yīng)屬性,IDE 會(huì)提供快捷鍵快速生成這些方法坠狡。
而現(xiàn)代 OC 可以直接使用 @property
的變量可以自動(dòng)生成 setter/getter 方法(早期 OC 不行继找,后來(lái)可以了),同時(shí)可以使用通過(guò)點(diǎn)語(yǔ)法去調(diào)用屬性逃沿,但點(diǎn)語(yǔ)法的本質(zhì)是調(diào)用類的 getter 方法和 setter 方法婴渡,如果類中沒(méi)有 getter 方法和 setter 方法就不能使用點(diǎn)語(yǔ)法幻锁,假如強(qiáng)行使用將編譯報(bào)錯(cuò)。這極大地簡(jiǎn)化了代碼編寫的工作量边臼,減少了很多重復(fù)的工作量哄尔。
方法訪問(wèn)權(quán)限
Java 中方法內(nèi)容都寫在了 .java
文件中,通過(guò) public
柠并、protect
究飞、不帶任何修飾符(默認(rèn)級(jí)別)和 private
去控制外部類是否有權(quán)限去訪問(wèn)相應(yīng)的方法。
而 OC 在寫 .h
文件中編寫的是公開(kāi)的屬性和方法堂鲤,而在 .m
文件中都會(huì)有具體的實(shí)現(xiàn)亿傅,可以在此文件書寫 .h
文件及其繼承下來(lái)和實(shí)現(xiàn)協(xié)議的方法中未出現(xiàn)的屬性和方法,而這些屬性和方法是都屬于私有的瘟栖,這樣有利于隱藏細(xì)節(jié)實(shí)現(xiàn)同時(shí)不需要改變頭文件葵擎。
我們應(yīng)該善于面向接口編程,劃清邊界半哟,將類的實(shí)現(xiàn)隱藏在調(diào)用者所見(jiàn)之外酬滤,使主調(diào)和被調(diào)者之間保持最少知識(shí)原則。
靜態(tài)語(yǔ)言 VS 動(dòng)態(tài)語(yǔ)言
首先普及一個(gè)知識(shí)點(diǎn)寓涨,什么是動(dòng)態(tài)語(yǔ)言? 動(dòng)態(tài)語(yǔ)言就是在運(yùn)行時(shí)來(lái)執(zhí)行靜態(tài)語(yǔ)言的編譯鏈接的工作盯串。這就要求除了編譯器之外還要有一種運(yùn)行時(shí)系統(tǒng)來(lái)執(zhí)行編譯等功能。
Java 的方法是與 class 靜態(tài)綁定的戒良,JVM
(Java 虛擬機(jī)) 采取了類似 C++ 的虛表機(jī)制体捏,在編譯的時(shí)候會(huì)生成 .Class
文件,Class 文件格式采用類似 C 語(yǔ)言結(jié)構(gòu)體的偽結(jié)構(gòu)來(lái)存儲(chǔ)數(shù)據(jù)糯崎,字段表集合和方法表集合是寫死的在文件內(nèi)的几缭。JVM 會(huì)在鏈接類的過(guò)程中,給類分配相應(yīng)的字段表和方法表固定的內(nèi)存空間沃呢。每個(gè)類對(duì)應(yīng)一個(gè)方法表年栓,這些都是存在于方法區(qū)中的。對(duì)于一個(gè) Java 程序員可能會(huì)覺(jué)得反射很強(qiáng)大(因?yàn)槲以?jīng)就是)薄霜,但研究下反射的原理某抓,反射是可以運(yùn)行動(dòng)態(tài)的調(diào)用某個(gè)對(duì)象的方法/構(gòu)造函數(shù)、獲取某個(gè)對(duì)象的屬性等惰瓜,但無(wú)法動(dòng)態(tài)添加字段 or 方法否副,因?yàn)榉瓷涞膶?shí)現(xiàn)是對(duì) JVM
內(nèi)存的方法區(qū)內(nèi)容進(jìn)行操作處理,字段表和方法表在類加載后內(nèi)存區(qū)域已經(jīng)被固定了鸵熟,無(wú)法動(dòng)態(tài)添加相關(guān)內(nèi)容進(jìn)行擴(kuò)展副编,同時(shí)通過(guò)原理可以了解到反射是對(duì) JVM
進(jìn)行操作,所以這也是為什么我們所說(shuō)反射效率并不高的原因,故我們一般只在極端的情況下才會(huì)使用痹届。
而由于 OC 使用消息傳遞呻待,底層大多還是 C 的內(nèi)容,一個(gè)類/對(duì)象的數(shù)據(jù)結(jié)構(gòu)其實(shí)就相當(dāng)是一個(gè)結(jié)構(gòu)體队腐,其中具有屬性表集合struct objc_ivar_list *ivars
和方法表集合struct objc_method_list **methodLists
蚕捉,所以我們可以使用 runtime(一套比較底層的純 C 語(yǔ)言 API,可以在運(yùn)行時(shí)來(lái)執(zhí)行靜態(tài)語(yǔ)言的編譯鏈接的工作)讓類柴淘、對(duì)象的屬性和方法可以在運(yùn)行時(shí)確定和修改迫淹,動(dòng)態(tài)添加新的屬性和方法,因?yàn)樘砑有碌膬?nèi)容不過(guò)相當(dāng)于給集合添加新元素为严。也就是說(shuō)敛熬,OC 會(huì)更加動(dòng)態(tài)一點(diǎn)。
最后再講講垃圾回收那點(diǎn)事
OC 垃圾回收使用的是引用計(jì)數(shù)器算法來(lái)搜索和處理不需要的對(duì)象內(nèi)存第股,但這種垃圾回收是在編譯期進(jìn)行處理应民,使用變量時(shí)相當(dāng)于多了一點(diǎn)點(diǎn)的計(jì)數(shù)器指令操作,故性能相比 C 語(yǔ)言僅僅略差一點(diǎn)點(diǎn)夕吻。然后 OC 以前是使用 MRC 手動(dòng)管理內(nèi)存(Manual Reference Counting)诲锹,而后來(lái)使用 ARC 自動(dòng)管理內(nèi)存(Automatic Reference Counting)。這是個(gè)十足的進(jìn)步涉馅,因?yàn)?OC 開(kāi)發(fā)者不再需要過(guò)多的關(guān)注內(nèi)存問(wèn)題(雖然內(nèi)存還是必須關(guān)注的)归园,而將更多的時(shí)間放在我們真正關(guān)心的事情上。
引用計(jì)數(shù)器算法
給每個(gè)對(duì)象設(shè)置一個(gè)計(jì)數(shù)器稚矿,當(dāng)有地方引用這個(gè)對(duì)象的時(shí)候庸诱,計(jì)數(shù)器+1,當(dāng)引用失效的時(shí)候盐捷,計(jì)數(shù)器-1偶翅,當(dāng)計(jì)數(shù)器為 0 的時(shí)候,就認(rèn)為對(duì)象不再被使用碉渡,是“垃圾”了,ARC 下該對(duì)象自動(dòng)設(shè)置為 nil母剥,而 MRC 需要手動(dòng)設(shè)置為 nil滞诺。實(shí)現(xiàn)簡(jiǎn)單,判斷效率高环疼。
而 Java 垃圾回收是 JVM
去處理的习霹,但是垃圾回收是運(yùn)行時(shí)進(jìn)行處理,一開(kāi)始版本也是使用引用計(jì)數(shù)器算法炫隶,但此算法很難解決循環(huán)引用問(wèn)題(A 對(duì)象引用 B 對(duì)象淋叶,B 對(duì)象又引用 A 對(duì)象,但是A, B對(duì)象已不被其他對(duì)象引用從而這兩個(gè)對(duì)象都不會(huì)被回收導(dǎo)致內(nèi)存泄漏)伪阶,同時(shí)每次計(jì)數(shù)器的增加和減少都帶來(lái)了很多額外的開(kāi)銷煞檩,所以在 JDK1.1 已廢棄处嫌,改用GC 搜索算法
根搜索算法
通過(guò)一系列的名為“GC Roots”對(duì)象作為起點(diǎn),從這些節(jié)點(diǎn)開(kāi)始往下搜索斟湃,搜索所有走過(guò)的路徑稱為引用鏈熏迹,當(dāng)一個(gè)對(duì)象沒(méi)有被 GC Roots 的引用鏈連接的時(shí)候,說(shuō)明這個(gè)對(duì)象是不可達(dá)的凝赛,證明該對(duì)象是可以被回收的
那問(wèn)題來(lái)了注暗,為什么 OC 就能解決循環(huán)引用的問(wèn)題呢?
OC 引入兩個(gè)概念墓猎,strong 指針和 weak 指針:默認(rèn)所有實(shí)例變量和局部變量都是 strong 指針捆昏,每被 strong 指針指向的對(duì)象計(jì)數(shù)器就自動(dòng)+1,失去一個(gè) strong 指針 指向則計(jì)數(shù)器-1毙沾,而弱指針指向的對(duì)象計(jì)數(shù)器不變化骗卜。兩端互相引用時(shí),一端用 strong搀军、一端用 weak膨俐,此處使用 Apple 官方的圖進(jìn)行說(shuō)明。
此時(shí)其他對(duì)象撤銷對(duì)下面兩個(gè) Object 對(duì)象之間的強(qiáng)引用罩句,就再也沒(méi)有對(duì)象對(duì) Delegate Object 具有強(qiáng)引用了焚刺。
因此 Delegate Object,即被 weak 的一端门烂,計(jì)數(shù)器為 0 了乳愉,故被回收了。
一但 weak 的對(duì)象也被回收屯远,就再也沒(méi)有對(duì)象對(duì) NSTableView 對(duì)象進(jìn)行引用蔓姚,此時(shí) NSTableView 對(duì)象計(jì)數(shù)器也為 0 了,也要被回收了慨丐。這就是 OC 雞賊坡脐,不不不,是機(jī)智處理循環(huán)引用的方法房揭。
這里普及一點(diǎn)备闲,Java 也是有強(qiáng)引用和弱引用這個(gè)概念的,具體如下:
- 強(qiáng)引用:正常使用變量那樣捅暴。即使內(nèi)存不足的時(shí)候也永遠(yuǎn)不會(huì)被垃圾回收恬砂。
- 軟引用:通過(guò) SoftReference 類實(shí)現(xiàn),當(dāng)內(nèi)存不足時(shí)會(huì)回收軟引用的對(duì)象蓬痒。
- 弱引用:通過(guò) WeakReference 類實(shí)現(xiàn)泻骤,不管當(dāng)前內(nèi)存空間足夠與否,只要 GC 后發(fā)現(xiàn)了就會(huì)回收它的內(nèi)存。
- 虛引用:跟蹤對(duì)象被垃圾回收的狀態(tài)狱掂,主要是實(shí)現(xiàn)細(xì)粒度的內(nèi)存控制演痒,使得該對(duì)象被立即回收,同時(shí)可以較快的通知該對(duì)象執(zhí)行 finalize 方法符欠,故可以在這個(gè)方法上做一些操作嫡霞。
總結(jié)
其實(shí)全面學(xué)習(xí)第二門主語(yǔ)言,相對(duì)難度會(huì)較大希柿,而且跳出舒適圈的勇氣需要非常大(所以當(dāng)時(shí)我剪了個(gè)光頭重頭開(kāi)始hhh)诊沪,因?yàn)樾枰粩嗳ミm應(yīng)一個(gè)新的語(yǔ)法糖,當(dāng)然也可能是 OC 的語(yǔ)法糖并不可愛(ài)!!!但學(xué)習(xí)新的語(yǔ)言的好處是非常好的曾撤,因?yàn)槟銜?huì)不斷你會(huì)不斷比較和了吐槽端姚,了解到哪些內(nèi)容是這個(gè)語(yǔ)言的瓶頸,就比如 Java 效率較低和語(yǔ)言不動(dòng)態(tài)挤悉、OC 不支持跨平臺(tái)和語(yǔ)法惡心等等渐裸。這些經(jīng)歷都有利于以后對(duì)其他語(yǔ)言的學(xué)習(xí),而且越學(xué)越快装悲。
現(xiàn)在天天是接觸 Mac 開(kāi)發(fā)昏鹃,但相對(duì)于封閉的開(kāi)發(fā)環(huán)境,其實(shí)還是比較喜歡開(kāi)源的感覺(jué)诀诊,因?yàn)樘O果爸爸太霸道了洞渤,只能長(zhǎng)期在一個(gè)需要猜測(cè)底層實(shí)現(xiàn)的平臺(tái)上開(kāi)發(fā)。但也還好属瓣,可能因?yàn)橐郧笆?Android 開(kāi)發(fā)者载迄,有研究過(guò)一點(diǎn)點(diǎn)源碼的內(nèi)容,對(duì)于一個(gè)操作系統(tǒng)抡蛙,其實(shí)有些內(nèi)容和機(jī)制大概也就那樣而已护昧,而且 IOS 可能還更簡(jiǎn)單,爸爸終究還是爸爸粗截。而且開(kāi)源社區(qū)中也有許多優(yōu)秀的開(kāi)源程序可供學(xué)習(xí)惋耙,不一定要死摳系統(tǒng)應(yīng)用,保持一顆學(xué)習(xí)的心就會(huì)不斷進(jìn)步的熊昌。