成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

iOS開發(fā)指南 內(nèi)存管理工作原理

移動開發(fā) iOS
在內(nèi)存管理的Objective-C代碼里,一個Cocoa對象存在于一個生命周期,有明確的階段。它被創(chuàng)建,初始化,并使用(也就是,其它對象發(fā)送消息給它)。它還可能會被保留,拷貝,或壓縮,并最終被釋放和銷毀。下面的討論以圖表形式對一個典型對象的生命周期進(jìn)行了描述,這里還沒有涉及更多的細(xì)節(jié)。

讓我們從后面開始,當(dāng)垃圾收集被關(guān)掉時對象銷毀的方式。在此背景下Cocoa和Objective-C 選擇一個自動的,策略驅(qū)動的過程來保持對象的存在并在不再被需要的時候銷毀它們。

這個過程和策略依賴于引用計(jì)數(shù)的概念。每個Cocoa對象攜帶一個整數(shù)用來指示對其存在感興趣的其它對象的數(shù)目。這個整數(shù)被稱為對象的保留數(shù)(retain count)(“retain”用來避免和術(shù)語“reference”重疊)。 當(dāng)你創(chuàng)建一個對象時,或者通過一個類工廠方法或者使用alloc 或allocWithZone: 類方法, Cocoa 做了一些很重要的事情:

它設(shè)置對象的isa 指針- NSObject 類的***公共成員變量-以指向這個對象的類,這樣把這個對象集成到運(yùn)行時視圖類層次。(參見對象創(chuàng)建“Object Creation”獲取更多信息)

它設(shè)置對象的保留數(shù)(retain count)- 一種由運(yùn)行時管理的隱藏的成員變量- 為1。(這里假設(shè)一個對象的創(chuàng)建者對其存在感興趣)

在對象分配后,你一般會設(shè)置它的成員變量為一個合理的初始值。 (NSObject 聲明init 方法作為這個目的的原形)。 這個對象現(xiàn)在已經(jīng)可以使用了;你可以發(fā)送消息給它,把它傳遞給其他對象,等等。

注意: 因?yàn)橐粋€初始化器可以返回一個不是顯式聲明的那個對象,慣例是嵌套alloc 消息表達(dá)式在init 消息里(或者其他初始化器)- 比如:

  1. <code>id anObj = [[MyClass alloc] init];</code> 

當(dāng)你釋放一個對象- 也就是,發(fā)送一個release 消息給它 – NSObject 減少其保留數(shù)。如果這個保留數(shù)從1變成0,這個對象會被釋放。釋放分成兩個步驟。首先,對象的dealloc 方法被調(diào)用來釋放成員變量并動態(tài)釋放分配的內(nèi)存。然后操作系統(tǒng)銷毀對象自身并回收該對象曾經(jīng)占用的內(nèi)存。

重要: 你永遠(yuǎn)不該直接調(diào)用一個對象的dealloc 方法。

要是你不想一個對象馬上消失?如果你在從別處接收到一個對象時給它發(fā)送了一個retain 消息,這個對象的保留數(shù)(retain count)被增加為2。現(xiàn)在在釋放之前需要兩個release 消息。圖2-4 圖示了這個相對簡化的場景。

Figure 2-4 一個對象的生命周期- 簡化視圖

 

當(dāng)然,在這個場景中,一個對象的創(chuàng)建者不需要保留這個對象。它早就擁有了這個對象。但是如果這個創(chuàng)建者在一個消息中傳遞這個對象給另外的對象,情況就發(fā)生了變化。在一個Objective-C 程序中,一個接收一些其他對象的對象總是假設(shè)在其獲得的范圍內(nèi)有效。這個接收對象可以發(fā)送消息給被接受的對象以及傳遞給其他對象。這個假設(shè)需要發(fā)送對象運(yùn)轉(zhuǎn)并且不會過早的釋放這個對象,當(dāng)一個客戶對象有一個指向它的引用時。

如果客戶對象想在接收到的對象程序訪問范圍之外保留它,可以retain 它- 也就是,發(fā)送一個retain 消息給它。保留一個對象增加其保留計(jì)數(shù),并由此表達(dá)該對象的一個所有權(quán)。這個客戶對象假設(shè)稍后釋放該對象的一個職責(zé)。如果一個對象的創(chuàng)建者釋放它,但是一個客戶對象保留了這個相同的對象,這個對象保持存在直到這個客戶釋放了它。圖2-5 說明了這個順序:

Figure 2-5 保留一個接收到的對象

 

和保留一個對象相反,你可以通過給它發(fā)送一個copy 或copyWithZone:消息來拷貝它。(很多子類,如果不是大多數(shù),封裝了一些采用或符合這個協(xié)議的數(shù)據(jù))。拷貝一個對象不僅復(fù)制它而且常常總是重置它的保留計(jì)數(shù)為1(參見圖2-6)。拷貝可以是淺拷貝也可以是深拷貝,這依賴于這個對象的本質(zhì)以及它的預(yù)期用途。一個深拷貝復(fù)制出一個可以承擔(dān)成員變量相同作用的對象,而淺拷貝僅僅增加這些成員變量的引用。

談到使用,區(qū)別一個copy 和retain 的是前者聲稱這個對象的單獨(dú)使用權(quán);新的擁有者可以改變這個拷貝對象而無須關(guān)心它的原始對象。一般而言你拷貝一個對象而不是保留它,當(dāng)它是一個數(shù)值對象- 也就是,一個對象封裝了一些基本數(shù)據(jù)(如整數(shù))。特別是這個對象本身是可變的,比如一個NSMutableString,對于非可變對象,copy和retain 可以等同并且也許可以用類似方法來實(shí)現(xiàn)。

Figure 2-6 拷貝一個接收到的對象

 

你 也許注意到了這個機(jī)制關(guān)于管理對象生命周期的一個潛在的問題。創(chuàng)建了一個對象并傳遞給另外的對象的這個創(chuàng)建者對象并不總是知道什么時候可以安全的釋放掉這 個被創(chuàng)建出來的對象。有可能在堆棧中有這個對象的多個引用,有一些是創(chuàng)建者對象所不知道的。如果這個創(chuàng)建者對象釋放掉這個被創(chuàng)建的對象然后其他對象給這個 已銷毀對象發(fā)送消息的話,程序?qū)⒈罎ⅰ榱讼@個問題,Cocoa 引入了一個延遲釋放的機(jī)制叫做autoreleasing。

Autoreleasing 使用自釋放池(autorelease pools) (以NSAutoreleasePool 類定義)。一個自釋放池是一個明確定義了范圍的對象集合,這個范圍標(biāo)記著最終什么時候釋放。自釋放池可以被嵌套。當(dāng)你發(fā)送一個 autorelease 消息, 一個該對象的引用被放進(jìn)最近的自釋放池中。它仍然是一個有效的對象,所以其他在自釋放池定義范圍內(nèi)的對象可以給它發(fā)送消息。當(dāng)程序執(zhí)行到范圍末尾時,這個池被釋放,而且,相應(yīng)的,池中的所有對象也將被釋放(參見圖2-7)。如果你在開發(fā)一個應(yīng)用程序你可能不需要建立一個自釋放池,因?yàn)閼?yīng)用程序工具箱(Application Kit)會自動建立一個范圍為應(yīng)用程序事件周期的自釋放池.

Figure 2-7 一個自釋放池

 

iPhone OS 提示: 因?yàn)樵趇Phone OS 中,應(yīng)用程序在一個更加內(nèi)存受限的環(huán)境中運(yùn)行,所以不鼓勵在應(yīng)用程序創(chuàng)建很多對象的方法或代碼段中使用自釋放池(比如,循環(huán))。相反,你應(yīng)該在任何可能的時候顯式的釋放對象。

到目前為止關(guān)于對象生命周期的討論集中在貫穿周期的對象管理機(jī)制上。但是一個對象擁有者策略指導(dǎo)如何使用這些機(jī)制。這個策略可以總結(jié)如下:

如果你通過分配并初始化來創(chuàng)建( create )一個對象(比如 [[MyClass alloc] init]),你將擁有這個對象并負(fù)責(zé)釋放它。這個規(guī)則同樣適用于使用NSObject 簡便方法(convenient method)new。

如果你拷貝(copy)一個對象,你將擁有這個拷貝的對象并負(fù)責(zé)釋放它。

如果你保留( retain )一個對象,你擁有該對象部分的所有權(quán)并且當(dāng)你不需要的時候釋放它。

相反的,如果你從其他一些對象接收一個對象,你不擁有這個對象并且不應(yīng)該釋放它。(這個規(guī)則有一些少數(shù)的例外,已在參考文檔中顯式的標(biāo)注)

和任何規(guī)則集一樣,有一些例外和已知問題(“gotchas”):

如果你通過類工廠方法創(chuàng)建了一個對象(比如NSMutableArray arrayWithCapacity: 方法),假設(shè)你接收的這個對象是自動釋放的。你不應(yīng)該自己釋放這個對象而且如果你想保持其存在的話應(yīng)該retain它。

為了避免循環(huán)引用,一個子對象永遠(yuǎn)不該retain它的父對象。(一個父對象是這個子對象的創(chuàng)建者或者一個以成員變量包含該這個子對象的對象。)

注意: 上面指南中的“Release”意味著發(fā)送一個release 消息或者一個autorelease 消息給一個對象。

如果你不遵循這個所有權(quán)策略,在你的應(yīng)用程序中很可能會發(fā)生兩件糟糕的事情。因?yàn)槟銢]有釋放創(chuàng)建,拷貝,或者保留的對象,你的應(yīng)用程序?qū)⒋嬖趦?nèi)存泄漏。或者當(dāng)你給一個已從其他地方釋放的對象發(fā)送消息時導(dǎo)致你的程序崩潰。這里還有一個警告:調(diào)試這些問題費(fèi)時費(fèi)力。

一個另外的可能發(fā)生在一個對象生命周期里的基本事件是歸檔(archiving)。歸檔把組成一個面向?qū)ο蟮某绦虻幕ハ嚓P(guān)聯(lián)的對象網(wǎng)絡(luò)-對象圖-轉(zhuǎn)換成一個持久格式(通常是一個文件),保存了標(biāo)識和每個圖中對象的關(guān)系。當(dāng)程序被解歸檔時,它的對象圖從歸檔中重新構(gòu)建。為了參與歸檔(和解歸檔),一個對象必須能夠編碼(和解碼)。它的成員變量使用NSCoder 類方法。 NSObject 采用NSCoding 協(xié)議來完成這個目的。更多關(guān)于對象歸檔的內(nèi)容,請參見對象歸檔(“Object Archives”)。

責(zé)任編輯:佚名 來源: blog.csdn
相關(guān)推薦

2012-12-27 16:21:11

2022-08-18 15:03:17

項(xiàng)目管理供應(yīng)鏈IT

2013-08-14 16:06:25

IT運(yùn)維虛擬化

2020-05-22 11:59:48

漏洞管理新基建

2009-02-05 19:03:05

動態(tài)資源分配虛擬機(jī)遷移Novell

2011-06-20 06:14:15

ibmdwLinux

2016-07-15 10:44:56

座席 管理

2009-01-15 09:53:00

遠(yuǎn)程管理局域網(wǎng)

2009-07-27 10:11:20

2014-06-10 09:56:05

iOSYOLOKitXcode

2011-03-02 08:35:19

人機(jī)交互界面iOS

2022-08-02 08:01:09

開發(fā)插件Chrome前端技術(shù)

2011-07-25 16:21:22

Sencha touc

2011-03-15 13:18:45

Oracle數(shù)據(jù)庫管理員

2009-02-24 20:45:53

軟考信息系統(tǒng)集成項(xiàng)目管理工作

2011-07-21 14:42:45

iOS UIViewCont 內(nèi)存

2017-11-30 08:53:28

Windows機(jī)器學(xué)習(xí)軟件方案

2009-06-24 16:30:21

JSF組件模型

2011-06-09 18:24:36

QT Wince

2012-03-26 09:27:40

谷歌安卓開發(fā)谷歌安卓
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 黄色毛片网站在线观看 | 久久久成人网 | 91极品尤物在线播放国产 | 亚洲另类自拍 | 国产精品成人国产乱一区 | 欧美 视频 | 欧美黄在线观看 | 在线视频中文字幕 | 成年人在线观看视频 | 亚洲第一在线 | 免费一级黄色录像 | 在线播放中文字幕 | 一区二区三区av | 久久高清 | 日韩欧美在 | 可以在线观看av的网站 | 免费国产网站 | 亚洲不卡在线观看 | 欧美九九 | 国产高清在线观看 | 99久热在线精品视频观看 | 久久成人人人人精品欧 | 成人激情视频在线 | 精品一区二区三区四区在线 | 精品国产伦一区二区三区观看说明 | 久久精品福利视频 | 亚洲啊v| 欧美一区二区三区在线免费观看 | 日韩精品| 中文字幕伊人 | 日韩精品无码一区二区三区 | av一区二区三区四区 | 99久久精品国产一区二区三区 | 亚洲精品一区二区三区丝袜 | 欧美成人免费在线视频 | 天天影视亚洲综合网 | 99国产精品久久久 | 国产一区二区三区免费 | 久草网址 | 久久免费小视频 | 欧美黑人一区二区三区 |