偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Cocoa基本原理指南 Cocoa對(duì)象 生命周期

移動(dòng)開發(fā) iOS
本文介紹的漢斯Cocoa基本原理指南 Cocoa對(duì)象 生命周期,Cocoa對(duì)象的生命周期(至少是潛在地)跨越不同的階段。先來(lái)看內(nèi)容。

Cocoa基本原理指南 Cocoa對(duì)象 生命周期是本文要介紹的內(nèi)容, Cocoa對(duì)象生命周期(至少是潛在地)跨越不同的階段。它需要被創(chuàng)建、初始化、和使用(就是其它對(duì)象向它發(fā)送消息),它可能被保持、拷貝、或者歸檔,并最終被釋放和銷毀。下面的討論將給出一個(gè)典型對(duì)象生命周期框圖,但仍然不涉及太多的細(xì)節(jié)。

讓我們從最后開始,即從清理對(duì)象的方式開始討論。和其它編程語(yǔ)言不同,Objective-C沒有自動(dòng)釋放不再使用的對(duì)象的“垃圾收集”設(shè)施。垃圾收集開銷大而且不靈活,取而代之的是,Cocoa和Objective-C選擇一種主動(dòng)的、策略驅(qū)動(dòng)的例程來(lái)保持對(duì)象,并在不再需要的時(shí)候進(jìn)行清理。

這種例程和策略建立在引用計(jì)數(shù)的基礎(chǔ)上。每個(gè)Cocoa對(duì)象都帶有一個(gè)整數(shù),用于指示對(duì)其持久性感興趣的其它對(duì)象(甚至是例程代碼的現(xiàn)場(chǎng))的數(shù)目。這個(gè)整數(shù)被稱為對(duì)象的保持?jǐn)?shù)(“保持” 是為了避免和“引用”重復(fù))。當(dāng)您通過alloc或者allocWithZone:類方法創(chuàng)建對(duì)象的時(shí)候,Cocoa做了一些非常重要的工作:

它將對(duì)象的isa指針—NSObject類中唯一的公共實(shí)例變量—指向?qū)ο蟮念?,因此將?duì)象集成到類層次的運(yùn)行時(shí)視圖中(進(jìn)一步信息請(qǐng)參見"對(duì)象的創(chuàng)建"部分)。

它將對(duì)象的保持?jǐn)?shù)—一個(gè)隱藏的實(shí)例變量,所有對(duì)象都有—設(shè)置為1(這里假定對(duì)象的創(chuàng)建者對(duì)其持久性感興趣)。

為對(duì)象分配內(nèi)存之后,您通常需要將其實(shí)例變量設(shè)置為合理的初始值,以便進(jìn)行初始化(NSObject聲明了init方法作為這個(gè)目的的原型)。這樣對(duì)象就可以使用了,您可以向它發(fā)送消息,將它傳遞給其它對(duì)象,等等。

請(qǐng)注意:由于除了顯式分配的對(duì)象之外,初始化方法也可以返回一個(gè)對(duì)象,因此習(xí)慣上將alloc消息嵌套在init消息(或其它初始化方法)中—舉例來(lái)說:

  1. id anObj = [[MyClass alloc] init]; 

當(dāng)您釋放一個(gè)對(duì)象—也就是向?qū)ο蟀l(fā)送一個(gè)release消息時(shí)—NSObject會(huì)減少它的保持?jǐn)?shù)。如果保持?jǐn)?shù)從1下降到0,對(duì)象就會(huì)被解除分配。對(duì)象的解除分配有兩個(gè)步驟:首先是對(duì)象的dealloc方法被調(diào)用,以釋放實(shí)例變量和動(dòng)態(tài)分配的內(nèi)存;然后是操作系統(tǒng)將對(duì)象的本身銷毀,并回收對(duì)象占用的內(nèi)存。

重要提示:您永遠(yuǎn)不應(yīng)該直接調(diào)用對(duì)象的dealloc方法。

如果您不希望對(duì)象很快消失,該怎么辦呢?如果您在創(chuàng)建對(duì)象之后向它發(fā)送一個(gè)retain消息,對(duì)象的保持?jǐn)?shù)就會(huì)增加到2。這樣,就需要兩個(gè)release消息才能導(dǎo)致對(duì)象的釋放。圖2-3描述了這種極為簡(jiǎn)單的場(chǎng)景。

Cocoa基本原理指南 Cocoa對(duì)象的生命周期

  對(duì)象的生命周期—簡(jiǎn)化視圖

當(dāng)然,在這個(gè)場(chǎng)景下,對(duì)象的創(chuàng)建者不需要保持對(duì)象,它已經(jīng)擁有對(duì)象了。但是,如果這個(gè)創(chuàng)建者要將對(duì)象傳遞給消息中的另一個(gè)對(duì)象,則情況就不一樣了。在Objective-C程序中,人們假定從其它對(duì)象接收到的對(duì)象在其被得到的作用域內(nèi)總是正當(dāng)?shù)摹X?fù)責(zé)接收的對(duì)象可以向被接收的對(duì)象發(fā)送消息,而且可以將它傳遞給其它對(duì)象。這個(gè)假設(shè)要求對(duì)象的發(fā)送者“行為規(guī)矩”,不要在客戶對(duì)象仍然擁有被發(fā)送對(duì)象的引用時(shí)將它過早釋放。

如果客戶對(duì)象在程序的作用域之外希望保持接收到的對(duì)象,則可以保持該對(duì)象—也就是向它發(fā)送一個(gè)retain消息。保持一個(gè)對(duì)象會(huì)增加該對(duì)象的保持?jǐn)?shù),從而表示希望擁有該對(duì)象??蛻魧?duì)象有責(zé)任在一段時(shí)間后釋放該對(duì)象。如果對(duì)象的創(chuàng)建者將該對(duì)象釋放,但同時(shí)有一個(gè)客戶對(duì)象已經(jīng)保持了該對(duì)象,則該對(duì)象會(huì)一直持續(xù)到客戶對(duì)象將它釋放為止。圖2-4說明了這個(gè)序列:

Cocoa基本原理指南 Cocoa對(duì)象的生命周期

保持接收到的對(duì)象

您可以不保持對(duì)象,而是通過發(fā)送copy或copyWithZone:消息來(lái)對(duì)其進(jìn)行拷貝(很多子類—如果不是大多數(shù)的話—都封裝了某種數(shù)據(jù)采納方法,或遵循這種協(xié)議)??截愐粋€(gè)對(duì)象不僅僅是對(duì)其進(jìn)行復(fù)制,而且?guī)缀蹩偸菍⑺谋3謹(jǐn)?shù)設(shè)置為1(請(qǐng)參見圖2-5)。根據(jù)對(duì)象的本質(zhì)和可能的用法,拷貝可以是淺拷貝,也可以是深拷貝。深拷貝將對(duì)象復(fù)制為被拷貝對(duì)象的一個(gè)實(shí)例變量,而淺拷貝只是復(fù)制那些實(shí)例對(duì)象的引用。

在用法方面,copy和retain的區(qū)別在于前者要求成為對(duì)象新的、唯一的擁有者;新的擁有者可以修改拷貝后的對(duì)象,而不考慮其原始對(duì)象。一般地說,您需要對(duì)值對(duì)象(即對(duì)某些簡(jiǎn)單的值進(jìn)行封裝的對(duì)象)進(jìn)行拷貝,而不是保持。特別是當(dāng)對(duì)象是可變的時(shí)候,比如一個(gè)NSMutableString對(duì)象。對(duì)于不可變對(duì)象,copy和retain可能是等價(jià)的,其實(shí)現(xiàn)方法也是類似的。

Cocoa基本原理指南 Cocoa對(duì)象的生命周期

拷貝接收到的對(duì)象

您可能已經(jīng)注意到,用這種策略管理對(duì)象生命周期有一個(gè)潛在的問題,就是創(chuàng)建一個(gè)對(duì)象并將它傳遞給另一個(gè)對(duì)象的對(duì)象本身并不總是知道什么時(shí)候可以安全地釋放對(duì)象。在調(diào)用堆棧中可能有多個(gè)該對(duì)象的引用,某些引用可能來(lái)自創(chuàng)建者不知道的對(duì)象。如果創(chuàng)建者對(duì)象釋放了其所創(chuàng)建的對(duì)象,而其它對(duì)象向這個(gè)已經(jīng)被銷毀的對(duì)象發(fā)送消息,程序就會(huì)崩潰。為了解決這個(gè)問題,Cocoa引入了一種延遲對(duì)象釋放的機(jī)制,稱為自動(dòng)釋放(autoreleasing)機(jī)制。

自動(dòng)釋放機(jī)制通過自動(dòng)釋放池(由NSAutoreleasePool類定義)來(lái)實(shí)現(xiàn)。自動(dòng)釋放池是位于顯式定義的作用域內(nèi)的一個(gè)對(duì)象集合,該作用域被標(biāo)志為最后釋放。自動(dòng)釋放池可以嵌套。當(dāng)您向一個(gè)對(duì)象發(fā)送一個(gè)autorelease消息時(shí),Cocoa就會(huì)將該對(duì)象的一個(gè)引用放入到最新的自動(dòng)釋放池。它仍然是個(gè)正當(dāng)?shù)膶?duì)象,因此自動(dòng)釋放池定義的作用域內(nèi)的其它對(duì)象可以向它發(fā)送消息。當(dāng)程序執(zhí)行到作用域結(jié)束的位置時(shí),自動(dòng)釋放池就會(huì)被釋放,池中的所有對(duì)象也就被釋放(參見圖2-6)。如果您正在開發(fā)應(yīng)用程序,可能不需要建立一個(gè)自動(dòng)釋放池,Application Kit會(huì)自動(dòng)建立一個(gè)自動(dòng)釋放池,其作用域?yàn)闉閼?yīng)用程序的事件周期。

Cocoa基本原理指南 Cocoa對(duì)象的生命周期

自動(dòng)釋放池

到目前為止,對(duì)象生命周期的討論主要關(guān)注整個(gè)周期中的對(duì)象管理機(jī)制。但是,指導(dǎo)如何使用這些機(jī)制的是對(duì)象的所有權(quán)策略。這個(gè)策略可以概括如下:

如果您通過分配和初始化(比如[[MyClass alloc] init])的方式來(lái)創(chuàng)建對(duì)象,您就擁有這個(gè)對(duì)象,需要負(fù)責(zé)該對(duì)象的釋放。這個(gè)規(guī)則在使用NSObject的便利方法new時(shí)也同樣適用。

如果您拷貝一個(gè)對(duì)象,您也擁有拷貝得到的對(duì)象,需要負(fù)責(zé)該對(duì)象的釋放。

如果您保持一個(gè)對(duì)象,您就部分擁有這個(gè)對(duì)象,需要在不再使用時(shí)釋放該對(duì)象。

反過來(lái),

如果您從其它對(duì)象那里接收到一個(gè)對(duì)象,則您不擁有該對(duì)象,也不應(yīng)該釋放它(這個(gè)規(guī)則有少數(shù)的例外,在參考文檔中有顯式的說明)。

和其它規(guī)則一樣,這些策略也有一些例外和經(jīng)常出錯(cuò)的地方:

如果您通過類工廠方法來(lái)創(chuàng)建對(duì)象(比如NSMutableArray arrayWithCapacity:方法),則可以假定您接收到的對(duì)象已經(jīng)自動(dòng)被放到自動(dòng)釋放池了。您不應(yīng)該自行將它釋放,如果您需要保持該對(duì)象,則應(yīng)該保持(retain)它。

為了避免循環(huán)引用,子對(duì)象不能保持它的父對(duì)象(父對(duì)象是該子對(duì)象的創(chuàng)建者,或者將該子對(duì)象作為實(shí)例變量持有的對(duì)象)。

請(qǐng)注意:在上面的原則中提到的“釋放”是指向?qū)ο蟀l(fā)送一個(gè)release或autorelease消息。

如果您沒有遵循這個(gè)所有權(quán)的策略,則可能導(dǎo)致您的Cocoa程序出現(xiàn)兩種不好的結(jié)果:由于沒有釋放自己創(chuàng)建、拷貝、或保持的對(duì)象,您的程序會(huì)發(fā)生內(nèi)存泄露;或者,由于向已經(jīng)解除分配的對(duì)象發(fā)送消息,您的程序發(fā)生崩潰。而且還會(huì)有進(jìn)一步的問題:調(diào)試這些問題可能相當(dāng)費(fèi)時(shí)間。

對(duì)象生命周期中可能發(fā)生的另一個(gè)基本事件是歸檔。歸檔是將組成一個(gè)面向對(duì)象程序中的相關(guān)對(duì)象形成的網(wǎng)狀結(jié)構(gòu)—對(duì)象圖—轉(zhuǎn)化為一種可持久的形式(通常是一個(gè)文件),該形式可以保存對(duì)象圖中對(duì)象的標(biāo)識(shí)和彼此之間的關(guān)系。在解檔時(shí),可以通過這個(gè)檔案重新構(gòu)造出程序的對(duì)象圖。為了參與歸檔(和解檔),對(duì)象必須支持通過NSCoder類定義的方法對(duì)實(shí)例變量進(jìn)行編碼(和解碼)。為了這個(gè)目的,NSObject采納了NSCoding協(xié)議。有關(guān)對(duì)象歸檔的更多信息,請(qǐng)參見"對(duì)象的歸檔"部分。

進(jìn)一步閱讀: 這個(gè)Cocoa對(duì)象生命周期概述揭示了這個(gè)主題的一些表面的東西。關(guān)于Cocoa對(duì)象內(nèi)存管理的更詳細(xì)討論,請(qǐng)參見Objective-C編程語(yǔ)言一書中的“Objective-C運(yùn)行系統(tǒng)”部分,以及Cocoa內(nèi)存管理編程指南中的內(nèi)容。

小結(jié):Cocoa基本原理指南 Cocoa對(duì)象生命周期的內(nèi)容介紹完了,希望本文對(duì)你有所幫助!

責(zé)任編輯:zhaolei 來(lái)源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-07-07 13:30:32

Cocoa Core

2011-07-07 14:46:10

Cocoa Xcode

2011-07-07 14:10:21

Cocoa 內(nèi)省 hash

2011-08-10 19:33:09

Cocoa對(duì)象

2011-08-15 16:09:44

Cocoa對(duì)象Objective-C

2012-01-12 14:37:34

jQuery

2011-07-07 13:59:49

Cocoa Objective- 根類

2011-06-17 16:23:49

Cocoa蘋果

2011-11-29 12:17:00

2009-02-24 09:43:00

IP電話原理

2011-08-11 15:46:55

CocoaCocoa Touch框架

2011-08-10 18:37:32

CocoaMac OS X

2011-06-17 15:57:46

CocoaXcode蘋果

2011-07-07 10:39:07

Cocoa 函數(shù)

2011-07-07 10:07:19

Cocoa 框架

2011-07-07 10:29:35

Cocoa 方法 框架

2011-06-15 17:02:02

CocoaiOS

2016-08-17 23:53:29

網(wǎng)絡(luò)爬蟲抓取系統(tǒng)

2021-02-08 21:40:04

SockmapBPF存儲(chǔ)

2019-11-28 10:45:28

ZooKeeper源碼分布式
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)