1. 程式人生 > >黑馬程式設計師--09 OC 記憶體管理

黑馬程式設計師--09 OC 記憶體管理

                           ------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! -------

1.管理範圍

任何繼承了NSObject的物件,對其他基本資料型別(intcharfloatdoublestructenum等)無效

補充:a. 區域性變數存放在棧中.物件存放在堆中.

b. 注意:   物件指標還是存放在棧中,物件本身佔用的記憶體存放在堆中

c. 放在棧裡面的內容不用外面管理,只要一段程式結束後,棧中的內容自動釋放。而堆中的記憶體是動態建立的,所以不能隨便釋放

2.物件的基本結構

a. 每個OC物件都有自己的引用計數器,是一個整數,表示

物件被引用的次數,即有多少人正在使用這個OC物件

b.每個OC物件內部專門有4個位元組的儲存空間來儲存引用計數器

3.計數器

引用計數器的作用

當使用allocnew或者copy建立一個新物件時,新物件的引用計數器預設就是1

當一個物件的引用計數器值為0時,物件佔用的記憶體就會被系統回收。換句話說,如果物件的計數器不為0,那麼在整個程式執行過程,它佔用的記憶體就不可能被回收,除非整個程式已經退出

引用計數器的操作

a.   retain    物件傳送一條retain訊息,可以使引用計數器值+1retain方法返回物件本身)

b.   release 物件傳送一條release訊息

,可以使引用計數器值-1

c.   retainCount可以給物件發retainCount訊息獲得當前的引用計數器值

物件的銷燬

a.   當一個物件的引用計數器值為0時,那麼它將被銷燬,其佔用的記憶體被系統回收

b.  dealloc  當一個物件被銷燬時,系統會自動向物件傳送一條dealloc訊息,一般會重寫dealloc方法,在這裡釋放相關資源,dealloc就像物件的遺言,一旦重寫了dealloc方法,就必須呼叫[super dealloc],並且放在最後面呼叫,不要直接呼叫dealloc方法

c.  一旦物件被回收了,它佔用的記憶體就不再可用,堅持使用會導致程式崩潰(野指標錯誤)

部分概念

a.殭屍物件:所佔用的記憶體已經被收回,不可在使用

b.野指標:指向殭屍物件的指標。野指標報錯,但是空指標不報錯。

c.空指標:沒有指向任何東西的指標,

注意:給空指標傳送訊息不會報錯,給野指標傳送訊息會報錯。

4.多物件記憶體管理

原則

只要還有人在用某個物件,那麼這個物件就不會被回收,只要你想用這個物件,就讓物件的計數器+1,當你不再使用這個物件時,就讓物件的計數器-1

誰建立,誰release

如果你通過allocnew[mutable]copy來建立一個物件,那麼你必須呼叫releaseautorelease,換句話說,不是你建立的,就不用你去[auto]release

retain,誰release

只要你呼叫了retain,無論這個物件是如何生成的,你都要呼叫release

總結

有始有終,有加就有減,曾經讓物件的計數器+1,就必須在最後讓物件計數器-1

程式碼規範

A.  只要呼叫了alloc,必須有release

注意: NSString *物件不是alloc產生的,所以不用release.

B.   set方法的程式碼規範

a.基本資料型別:直接賦值    _age  =  age;     - (void)setAge:(int)age{ _age  = age; }

 b.OC物件型別

- (void) setCar:(Car *)car

{

if( car != _car )//判斷是否為新傳入的物件

{

[_car  release];//對就物件做一次release

_car = [car    retain];//對新物件做一次retain

}

     }

C.dealloc程式碼規範

一定要[super dealloc],而且要放到最後 

self(當前)所擁有的的其他物件做一次release操作

 -voiddealloc

 { [_car release];

 [super dealloc]; }

@property引數

控制set方法的記憶體管理

retain release舊值,retain新值(用於OC物件)

assign:直接賦值,不做任何記憶體管理(預設,用於非OC物件型別)

copy   release舊值,copy新值(一般用於NSString *

控制需不需生成set方法

readwrite:同時生成set方法和get方法(預設)

readonly  :只會生成get方法

多執行緒管理

atomic    :效能低(預設)

nonatomic:效能高(一般選用這個)

控制set方法和get方法的名稱

setter設定set方法的名稱,一定有個冒號:   

getter設定get方法的名稱

修改setget方法的名稱,主要用於布林型別。因為返回布林型別的方法名一般以is開頭,修改名稱一般用在布林型別中的getter

  @propery(setter=setAbc,getter=isRich) BOOL rich;

       BOOL b=p.isRich;//呼叫 

5.類的迴圈引用

1. @class 

使用場景對於迴圈依賴關係來說,比方A類引用B類,同時B類也引用A

#import "B.h" #import "A.h"
@interface A:NSObject @interface B:NSObject
{ {
B *b; A *a;
} }
@end @end


使用#import程式碼編譯會報錯。當使用@class在兩個類相互宣告,就不會出現編譯報錯

@class#import的區別

#import方式會包含被引用類的所有資訊,包括被引用類的變數和方法;@class方式只是告訴編譯器在A.h檔案中 B *b 只是類的宣告,具體這個類裡有什麼資訊,這裡不需要知道,等實現檔案中真正要用到時,才會真正去檢視B類中資訊

如果有上百個標頭檔案都#import了同一個檔案,或者這些檔案依次被#improt,那麼一旦最開始的標頭檔案稍有改動,後面引用到這個檔案的所有類都需要重新編譯一遍,這樣的效率也是可想而知的,而相對來講,使用@class方式就不會出現這種問題了

.m實現檔案中,如果需要引用到被引用類的實體變數或者方法時,還需要使用#import方式引入被引用類

迴圈retain

比如A物件retainB物件,B物件retainA物件 

這樣會導致A物件和B物件永遠無法釋放

解決方式

一端使用retain,一端使用assign(使用assign的在dealloc中也不用再release

6.autorelease的基本用法

給某個物件傳送一條autorelease訊息時,就會將這個物件加到一個自動釋放池中

當自動釋放池銷燬時,會給池子裡面的所有物件傳送一條release訊息

呼叫autorelease方法時並不會改變物件的計數器,並且會返回物件本身

autorelease實際上只是把對release的呼叫延遲了,對於每一次autorelease,系統只是把該物件放入了當前的autorelease pool中,當該pool被釋放時,該pool中的所有物件會被呼叫Release

自動釋放池的建立

@autoreleasepool

{

    // ....

}

a.在程式執行過程中,可以建立多個自動釋放池,它們是以棧的形式存在記憶體中

b.OC物件只需要傳送一條autorelease訊息,就會把這個物件新增到最近的自動釋放池中(棧頂的釋放池)

Book *book = [[[Book alloc] init] autorelease];

注意

對小記憶體的物件,可以使用 @autorelease代替 release

規律

一般來說,除了allocnewcopy之外的方法建立的物件都被聲明瞭autorelease

比如下面的物件都已經是autorelease的,不需要再release

NSNumber *n = [NSNumber numberWithInt:100];

NSString *s = [NSString stringWithFormat:@"jack"];

NSString *s2 = @"rose";

一般可以為類新增一個快速建立物件的類方法
+ (id)person {
 //  GoodPerson呼叫+ (id)personWithAge:(int)age後返回GoodPerson型別的物件
    return [[[self  alloc] init] autorelease];
}
+ (id)personWithAge:(int)age
{GoodPerson *p = [GoodPerson personWithAge:10];//子類
Person *p = [self person];
p.age = age;
return  p;
}


注意:

在新建物件時,使用[self alloc] 而不是 [類名 alloc]方便子類呼叫時能夠返回子類的物件這樣的類方法通常以類名開頭系統自帶的這類方法也是帶有autorelease.

結論:當方法內部建立物件時,儘量使用self,一滿足子類需求

缺點:不能精確控制物件何時release,所以適用小物件,

好處:不用再擔心物件釋放的時刻

7.ARC的使用

見到alloc,new,copy,retain,它會在合適的地方,自動release

指標分兩種強指標__strong (預設)  弱指標__weak

ARC是編譯器特性預設指向物件的指標都是強指標,使用__weak標記的是弱指標.如果沒有強指標指向物件了,這個物件就會被銷燬 (編譯器會自動新增 retain, release程式碼).如果物件被銷燬了,指向它弱指標會被自動清空,以防野指標錯誤。

_weak Person *p 弱指標

ARC特點

a.不允許使用release, autoreleaseretain, retainCount

b.允許重寫dealloc但是不允許呼叫 [super  dealloc];

[email protected]引數

strong:成員變數是強指標,相當於retain(適用於OC物件)以前寫retain現在全部改成strong

weak:   成員變數是弱指標,相當於assign(適用於OC物件)

assign :  適用於非OC物件

有了ARC就不需要關注記憶體管理了,怎麼寫都不會錯.

兩端迴圈引用解決方案

a.ARC:一端strong  一端weak

b.ARC:一端retain  一端assign

相關推薦

黑馬程式設計師09 OC 記憶體管理

                           ------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! ------- 1.管理範圍 任何繼承了NSObject的物件,對其他基本資料型別(int、char、float、double

黑馬程式設計師——7k面試題——交通燈管理系統

需求如下: 非同步隨機生成按照各個路線行駛的車輛。 訊號燈只考慮紅綠燈 要考慮左轉車輛控制訊號燈,右轉車輛不受訊號燈控制 具體訊號燈控制邏輯與顯示生活中交通控制邏輯上相同 每量車共過路口為1秒 隨機生成車輛時間間隔及紅綠燈交換時間間隔自定,可設定 不用GUI,用log展現

黑馬程式設計師OC記憶體管理

(一)手動管理記憶體 棧:存放區域性變數(所佔用記憶體會自動銷燬) -> 指向堆空間 堆:存放物件(所佔用記憶體需手動銷燬) 管理範圍:所有繼承NSObject的類物件 1.記憶體洩露?記憶

黑馬程式設計師————OC記憶體管理_筆記整理(二)

一、@Prpperty引數 // 加上retain:表示生成的set方法,release舊值,retain新值 @property (retain) Book *book; // oc物件型別 //@property (nonatomic,retain) 類名 *屬性名

黑馬程式設計師 OC基礎: 記憶體管理

記憶體管理 簡述 每個 oc 物件都有自己的引用計數器,是一個整數,表示”物件被引用的次數”.佔四位元組 計數器預設值為1 當為0時,物件佔用的記憶體會被系統回收. 引用的操作 給物件傳送一條 retain 計數器+1 給物件傳送一

黑馬程式設計師-OC學習筆記-----記憶體管理

移動裝置的記憶體極其有限,每個app所能佔用的記憶體是有限制的.當app所佔用的記憶體較多時,系統會發出記憶體警告,這時得回收一些不需要再使用的記憶體空間。比如回收一些不需要使用的物件、變數等。基本的資料型別是放在記憶體的棧裡面,這是不需要我們去管理的,系統會自動回收。但是

黑馬程式設計師——OC記憶體管理

1.記憶體的建立和釋放 讓我們以Object-c世界中最最簡單的申請記憶體方式展開,談談關於一個物件的生命週期。首先建立一個物件: id testObject = [[ClassName alloc] init]; //“ClassName”是任何你

黑馬程式設計師——OC筆記之記憶體管理

Objective-C提供了三種記憶體管理方式: MannulReference Counting(MRC,手動管理, iOS4.1之前的版本) automatic reference counting(ARC,自動引用計數,iOS4.1 之後推出的) garbage collection(垃圾回收)。iO

[黑馬程式設計師][OC]記憶體管理

一、記憶體管理的基本原理 1.什麼是記憶體管理 移動裝置的記憶體極其有限,每個app所能佔用的記憶體是有限制的,當app所佔用的記憶體較多時,系統會發出記憶體警告,這時得回收 一些不需要再使用的記憶體空間。比如回收一些不需要使用的物件、變數等。管理範圍:任何繼承了NS

黑馬程式設計師————OC記憶體管理_ARC

ARC( Autom Reference Counting) 是一個編譯器特性,會自動檢測幫我們release 一、ARC基本原理 1.編譯器特性 編譯程式碼的過程中會自動檢測哪裡需要插入自動釋放記憶體的程式碼 // 新建立一個物件,會自動釋放物件 P

黑馬程式設計師OC語言基礎—記憶體管理

之前我們已經提到過C語言中的記憶體儲存空間。有五大區域:堆、棧、自由儲存區、全域性\靜態儲存區和常量儲存區。 OC是以C語言為基礎的,所以也分這五大區域。 下面我們討論一下OC中記憶體管理的規律。 一、引用計數器 1.每個OC物件都有自己的引用計數器,是一個整數,即物件被

黑馬程式設計師-----OC記憶體管理原則

------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! ------- Objective-C對記憶體管理的方法

黑馬程式設計師——IOS基礎——OC記憶體管理

=====================引用計數器開始==================== 基本型別資料存放在棧中,物件存放在堆中 棧中的資料系統自動回收 堆空間中的資料動態分配,不能自動分配,容易引起記憶體洩露 需要給物件傳送訊息,讓它回收,即呼叫物件的回收方法

黑馬程式設計師----oc加強筆記----記憶體管理

                              引用計數器: 每個OC物件都有自己的引用計數器,是一個整數表示物件被引用的次數,即現在有多少東西在使用這個物件。物件剛被建立時,預設計數器值為1,當計數器的值變為0時,則物件銷燬。                 2)對引用計數器的操作     

黑馬程式設計師——OC基礎—記憶體管理

=== 記憶體管理機制 === OC的區域性變數在程式碼塊結束時被系統銷燬, 記憶體被回收. OC的物件, 內部有引用計數器, 當引用計數器的值為0時, 被系統銷燬, 記憶體被回收. 區域性變數存放在棧中. 物件存放在堆中. 注意, 物件指標還是存放在棧中, 物件本身佔用的記憶體存放在堆中. 在OC

黑馬程式設計師——OC基礎---記憶體管理

1. 控制set方法的記憶體管理 retain : release舊值,retain新值(用於OC物件)  assign : 直接賦值,不做任何記憶體管理(預設,用於非OC物件型別) copy   : release舊值,copy新值(一般用於NSString *) 2.  控制需不需生成set方法 re

黑馬程式設計師-----OC記憶體管理(二)

---------------------- ASP.Net+Unity開發、.Net培訓、期待與您交流! ---------------------- OC記憶體管理1>記憶體管理原則 ①只要還有人在用某個物件,那麼這個物件就不會被回收;只要想用這個物件,就讓計數

黑馬程式設計師——OC基礎——記憶體管理(一)

一,為什麼要進行記憶體管理 1,由於移動裝置的記憶體有限,所以每個APP所佔的記憶體也是有限制的,當APP所佔用的記憶體較多時,系統就會發出警告,這時就需要回收一些不需要繼續使用的記憶體空間,比如回收一些不再使用的物件和變數等。 任何繼承NSObject的物件,對其他的基

黑馬程式設計師------OC基礎-----記憶體管理

------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! ------- 法則 誰建立記憶體誰就要釋放記憶體 管理機制 引用計數器 1使用alloc(相當於C語言中的malloc)為物件分配記憶體,使用dealloc(相當與C語言中的fre

黑馬程式設計師---oc 記憶體管理

——Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! ——- 一、基本原理 (一)為什麼要進行記憶體管理。   由於移動裝置的記憶體極其有限,所以每個APP所佔的記憶體也是有限制的,當app所佔用的記憶體較多時,系統就會發出記憶體