objective C程式 記憶體管理

2021-07-04 07:09:31 字數 4137 閱讀 9035

記憶體管理

記憶體管理概念

由於移動裝置的記憶體機器有限所以每個被占用的記憶體也是有限的。不用的記憶體是需要**的,否則程式會崩潰

oc 管理記憶體的範圍: 管理任何繼承nsobject的物件,對其他的基本資料型別無效

基本資料型別資料占用的儲存空間是固定的 一般儲存在棧區。

物件型別是程式執行過程中動態分配的,儲存在堆區,記憶體管理主要是 對堆區的物件 的記憶體管理

引用計數器

每個oc物件都有自己的引用計數器,是乙個整數表示物件被引用的次數,即同一時間有多少東西在使用這個物件,物件剛被建立時,預設計數器值為1,當計數器值變為0時,物件被銷毀。

在每個oc物件內部,都專門有4個位元組的儲存空間來儲存引用計數器。

引用計數器的作用 : 用來判斷物件是否**的唯一依據(存在一種例外:物件值為nil時,引用計數為0,但不**空間)就是計數器是否為0,若不為0則存在。

引用計數器的操作

retain使得引用計數器 +1

release使得引用計數器 -1

retaincount 得到引用計數器的值    %ld   %tu

物件的銷毀

當乙個物件的引用計數器為0時

,那麼它將被銷毀

,其占用的記憶體被系統**。

當物件被銷毀時

,系統會自動向物件傳送一條

dealloc訊息,

一般會重寫

dealloc方法,

在這裡釋放相關的資源

,dealloc

就像是物件的

「臨終遺言」。

一旦重寫了

dealloc

方法就必須呼叫

[super dealloc],

並且放在**塊的最後呼叫

(不能直

接呼叫dealloc方法)

。一旦物件被**了

,那麼他所佔據的儲存空間就不再可用

,堅持使用會導致程式崩潰(野指

針錯誤)。

注意:1)dealloc 方法是nsobject 的,一般我們要重寫dealloc方法

2)在dealloc 方法內部,要呼叫[super dealloc];

#import

@inte***ce person : nsobject

@end

#import "person.h"

@implementation person

//dealloc方法,是物件臨終的遺言方法

//物件被銷毀時,會預設的呼叫該方法

//dealloc方法 是系統根據引用計數器的值,自動呼叫的

- (void)dealloc注意:永遠不要直接通過物件呼叫dealloc方法。物件一旦被**不可再用,堅持使用會使程式崩潰

3.記憶體管理的原則

如果物件有人使用,就不應該**

如果你想使用這個物件,應該讓這個物件retain  一次

如果你不想使用這個物件你應該然然這個物件release  一次

誰建立誰 release

誰retain 誰release

#import

@inte***ce dog : nsobject

-(void)eat;

@end

#import "dog.h"

@implementation dog

-(void)eat

p 在棧區   [person new];在堆區

如果棧區的已經被釋放了,而堆區的空間還沒有被釋放,堆區的空間就被洩露了

注意: p=nil 空指標沒有志向任何店東西的指標 ,給空指標傳送訊息不會報錯。

5.單個物件的記憶體管理

#import

@inte***ce dog : nsobject

- (bool)comparecolorwithother:(dog*)dog;

@end

#import "dog.h"

@implementation dog

- (bool)comparecolorwithother:(dog*)dog@end

#import

#import "dog.h"

int main(int argc, const char * argv) //自動釋放池結束 p物件被**

好處(1)不再需要關心物件釋放的時間  (2)不需要關心社麼時候呼叫release

autorelease是什麼原理

autorelease實際上只是把release的呼叫延遲了,對每個autorelease ,系統只是把該object放入了當前的autorelease pool中,當該pool被釋放時,該pool中的所有object會被呼叫release。

autorelease 的使用注意

1)並不是所有的放到自動釋放池中的**,產生的物件就會自動釋放,如果需要釋放,必須加入到自動釋放池

person *p =[[person new] autorelease];

我們只需要在自動釋放池**塊中呼叫autorelease就可以把物件加入到自動釋放池

2)如果物件呼叫;autorelease 但是,呼叫autorelease的時候,沒有在任何乙個自動釋放池中,此時該物件也不會被加入到自動釋放池

自動釋放池的棧結構(資料結構),和記憶體的棧區是不一樣的物件在 位於棧頂的釋放池

自動釋放池的應用

nsstring * str = [nsstring stringwithformat:@"***x"];

nsarray * array =[nsarray array]

person 類方法:

幫我們自動建立物件,並且管理物件的記憶體(加入到自動釋放池)

person *p =[person person];

1)建立乙個物件 p

2)用完之後,系統把物件釋放掉p

person *p =[[person alloc] init];

p autorelease;

+(id)person{

//建立物件

return [[[person alloc] init] autorelease]; //返回物件空間

//能夠幫我們把物件給加入到自動釋放池

快速建立乙個學生類初始化年齡

#import

@inte***ce student : nsobject

@property (nonatomic,assign) int age;

- (instancetype)initwithage:(int) age;

+ (instancetype)studentwithage:(int)age;

@end

#import "student.h"

@implementation student

//重寫構造方法給年齡初始化

- (instancetype)initwithage:(int) age{

//初始化父類判斷有沒有成功

if (self = [super init]) {

//初始化子類。賦值年齡。

_age =age;

return self;

+ (instancetype)studentwithage:(int)age{

return    [[[student alloc]initwithage:age]  autorelease];

-(void)dealloc{

nslog(@"student dealloc");

[super dealloc];

@end

#import

#import "student.h"

int main(int argc, const char * argv) {

@autoreleasepool {

student *stu =[[student alloc] initwithage:18];

nslog(@"stu.age = %d",stu.age);

[stu release];

//快速建立乙個物件 給年齡初始化

//1)定義類方法

//2)類方法有引數,傳遞乙個年齡

student *stu1 =[student  studentwithage:18];

nslog(@"stu1.age = %d",stu1.age);

return 0;

ios 記憶體管理,objective c記憶體管理

整理下筆記,如有不準備的地方,望指正。雖然現在蘋果已經大力推崇arc自動記憶體管理,記憶體管理已經不需要我們手動處理,作為新手,還是要了解一下。首先如果是5.x以上版本的xcode,xcode建立新project的時候預設是適用arc的,如果想自己管理記憶體 可以在edit scheme中設定obj...

Objective C記憶體管理

objective c的物件記憶體管理是一件非常有意思的事情,由其是在iphone嵌入式裝置中 想玩的省心點,就得熟知它的管理規則,由其是記憶體的管理機制。了解它的品性了才能在cocoa的世界裡如魚得水。否則,反之 如水得魚!1,乙個物件可以有乙個或多個擁有者 2,當它乙個擁有者都沒有時,它就會被 ...

Objective C記憶體布局

第2章 c變數 當用大多數常見的指令碼程式語言編寫乙個程式時,幾乎不必花時間來考慮變數。只是在使用變數時才建立它們,並且不必擔心用完它們之後會發生些什麼。語言的直譯器會負責所有的細節。當你在編譯語言中編寫 時,事情就沒那麼簡單了。必須告訴編譯器每個變數的型別和名稱,以宣告任何將要在程式中使用的變數。...