中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

OC的內存管理

發布時間:2020-06-28 10:16:05 來源:網絡 閱讀:692 作者:飛奔的土豆 欄目:開發技術

1.內存泄露

一般我們常說的內存泄漏是指堆內存的泄漏。堆內存是指程序從堆中分配的,大小任意的(內存塊的大小可以在程序運行期決定),使用完后必須顯式釋放的內存。應用程序一般使用malloccallocrealloc等函數(C++中使用new操作符)從堆中分配到一塊內存,使用完后,程序必須負責相應的調用freedelete釋放該內存塊,否則,這塊內存就不能被再次使用,我們就說這塊內存泄漏了。

2. 內存管理

堆中的內存都是手動開辟和手動釋放的。因此我們要時刻統計堆的指針有哪些是指向同一個的。再釋放時,確認所有指向這個堆的指針,都已經用完了,不再使用。但這個存在先天的不足,畢竟程序員在統計指針是否用完時,受到多方面的影響而不能正確統計,程序在聯合開發的時候,指向同一個的堆的指針就很難統計,因此必須有一個合理的方法來管理內存。

3. 理解內存管理到底干了什么?

OC中的內存管理實際上就是一種PV操作,就是對計數器的加減操作。基類NSObject存在一個計數器retainCount,并會被子類所繼承。alloc創建對象時,計數器+1retain純粹的計數器+1release將計數器減1,不是真的free掉一個對象,release時本著個人顧個人的原則。

4. release原則(黃金法則)

當我們用allocretainnewcopymutablecopy這些函數創建地址付給指針時,需要用release或者autorelease釋放。釋放的時候,每個指針誰創建的誰釋放,不能去釋放別人創建的指針。

5. 成員變量為對象的set函數

一個類的成員變量為另一個類的對象時,為了考慮內存管理,set函數的一般寫法,以Car類擁有Engine對象作為成員變量為例:

-(void)setEngine:(Engine *)newengine

{

if(engine!=newengine){ //判斷是否自我賦值

[engine release]; //若為對象賦新值,先release舊的

engine=[newEngine retain]; //賦新值且retain一下計數器+1

}

return;

}

 

這個set函數充分的考慮到了,自我賦值和對象取新值的情況,engine為空時,[engine release]執行一次,但不會產生效果,所以不會出現錯誤。因為OC在創建對象時,成員變量默認為nil[nil release]能夠執行,但是沒有效果,即不會對計數器產生影響。但是存在一個問題,就是賦新值后retain后,使用完成后會發現無法對其release,因為car類對象一直使用著這個值,car對象銷毀,才執行retain一次,減少engine計數器一次。因此必須重寫Car類的dealloc函數,在car對象釋放時,release一下engine,以對應set函數中的retain,滿足黃金法則。

重寫的dealloc函數為:

-(void)dealloc //car的對象釋放時,自動調用,類似析構函數

{

[engine release]; //self.engine=nil;作用相同(調用set函數)

[surper dealloc]; //模擬C++析構時,調用父類的析構函數

return;

}

6. 特殊成員變量的點語法

不同于普通變量,setget函數封裝應為:

@property (retain) Engine * engine;

@synthesize engine;

這樣就不用麻煩的自己書寫set函數了。一個類的成員是另一個類時,此時 set函數會與以前的普通成員邊量set函數大有不同,set函數書寫為內存 管路版本使用時,一定要重寫dealloc函數,處理成員對象的最后一次release

7. atuoreleaseatuoreleasepool

新版的自動釋放池寫法為;

@autoreleasepool

{

}

釋放池作為一個關鍵字存在,老版本的釋放池的書寫更易于理解,寫法如下:

NSAutorelease *pool = [[NSAutoreleasePool alloc]init];

…………

[pool release];

可以將pool看為一個數組,將relase的對象裝在這個數組中,等到釋放池 釋放的時候,才把池中的對象全部執行一次release

8. 以對象dog為例,使用自動釋放池release

[dog autorelease]; //自動釋放 延遲釋放

這里是將dog地址添加到pool中,pool執行release時,才把池中的對象全 部執行一次release。在這之前,計數器并沒有真正的減一,pool釋放的時 dog的計數器才會真正的減一。

9. 不到萬不得已的時候,千萬不要用autoreleasepool

IOS中每一個觸發周期,系統都會自動創建一個自動釋放池,在周期結束時, 就會釋放這個poolautorelease自動匹配最近的一個pool,我們并不能控 制其在我們想要釋放的時候才釋放。

+函數創建一個對象時,并不能確定何時釋放對象,因此我們在pool釋放時, 再釋放這個對象,避免錯誤。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

江北区| 东海县| 武陟县| 枣庄市| 泉州市| 鹤峰县| 永登县| 资溪县| 南木林县| 澎湖县| 光泽县| 鄱阳县| 维西| 驻马店市| 白朗县| 汉寿县| 和平县| 峨眉山市| 休宁县| 上林县| 民乐县| 涿鹿县| 德庆县| 儋州市| 灵山县| 新乡县| 蓬莱市| 阳东县| 颍上县| 滕州市| 三门县| 汤原县| 深州市| 淳化县| 沙坪坝区| 垦利县| 哈巴河县| 肇庆市| 武定县| 闵行区| 绵阳市|