程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Object C 內存管理

Object C 內存管理

編輯:關於C語言

Object C 內存管理
一.     基本概念:

1.   iPhone系統中的Objective-C的內存管理機制是比較靈活的,即可以拿來像C/C++一樣用,也可以加個AutoreleasePool讓它升級為半自動化的內存管理語言;
2.   引用計數是實例對象的內存回收唯一參考

引用計數(retainCount)是Objective-C管理對象引用的唯一依據。調用實例的release方法後,此屬性減一,減到為零時對象的dealloc方法被自動調用,進行內存回收操作,也就是說我們永不該手動調用對象的dealloc方法.

3.   “擁有的概念”

1) 擁有一個對象的使用權,我們稱為擁有這個對象;對象的擁有者個數至少為1,對象才得以存在,否則它應該立即銷毀;

2) 獲得一個對象所有權的方法:當對對象做alloc,copy,和retain操作之後;

4.   “引用”d的概念

面向對象領域裡有個引用的概念,區別於繼承,引用常被用來當做偶合性更小的設計。一個實例擁有另一個實例的時候,我們稱它為引用了另一個實例。

 

比如ClassA類的一個屬性對象的Setter方法:

- ( void )setMyArray:(NSMutableArray *)newArray {

     if (myArray != newArray) {

         [ myArray setMyArray:nil ];// 這裡不用release思考為什麼,(在實例的dealloc方法中會調用myArray的realse方法)

         myArray = [newArray retain];

     }

}

     

5.   引用記數:

每個對象都有一個引用記數(retainCount),對象被創建的時候引用記數為1;

6.   2

 

二.      內存管理API及使用准則:

1.    alloc:為一個新對象分配內存,並且它的引用記數為1;調用alloc方法,你便擁有新對象的所有權;

2.    copy:制造一個對象的副本,改副本的retainCount為1,調用者擁有對副本的所有權;

3.    retain: 使retainCount+1;並且擁有對象所有權;

4.    release:使retainCount-1;

5.    autorealse: 未來的某個時刻使retainCount-1;

6.    dealloc:不要手動調用,而是在系統retainCount為0時自動調用;

-      (void)dealloc{

[name  release];

[super dealloc];

}變量的release順序與初始順序相反;

三.     內存管理的原則:

以 1 2 3為A類,(retainCount+1);

以 4,5為B類:retainCount-1

1 .對於同一個對象所做的,A與B的調用次數保持一致;

2. 凡是通過alloc,retain,copy等手段獲得對象的所有權;必須在不適用的 使用自己調用release或autoRelease釋放;

3. 不要釋放不屬於自己的對象;

4. autorelease只是意味著延遲發送一個release消息;

5. 對於便利構造器和訪問器來說,不用進行釋放,因為沒有獲得對象的使用權;

四.     使用小例子:

1.

Person *person1 = [[Person alloc] initWithName:@”張三”];

NSLog(@”name is %@”,person1.name); //假設從這往後,我們一直都不使用person1 了,應該把對象給釋放了。

[person1 release];

2.

erson *person2 = [Person alloc]initWithName:@”李四”];

NSString *name = person2.name;NSLog(@”%@”,name); //假設從這以後,我們也不使用person2了。

[person2 release];

//不應該釋放name,因為name是我們間接獲得的,所以沒有它的所有權

 

3. 由便利構造器產生的對象不應當使用者銷毀,而是由便利構造器本身完成。
 

+(id) personWithName:(NSString *)aName

{

Person *person = [[Person alloc]

initWithName:aName];

return person; }

①錯誤,因為返回person對象後,類失去了釋放這個對象的機會;

②如果在return語句前加上:[person release];也錯誤,因為對象已經銷毀,不能使用;

③:正確做法:return語句前加上:[person autorelease];

 

(二)使用便利構造器創建的對象,不需要進行釋放;

如:

-(void) printHello

{

NSString *str = [NSString

stringWithFormat:@”Hello”];

NSLog(@”%@”,str); }

 

4. 訪問器和設置器:

 

1)在設置器中,保持對新傳入對象的所有權,同時放棄舊對象的所有權。

 

-(void) setName:(NSString *) aName{ if(name!= aName){

[name release];//有疑問,會不會造成多次釋放;

name = [aName retain];//or copy }

}

2) 在訪問器中,不需要retain或release.

 

-(NSString *)name{

return name; }

 

3) 用訪問器獲得的對象,使用完畢後不需要釋放。

 

-(void) printName{

NSString *name = person.name;

NSLog(@”%@”,name); }

 

5. 常見錯誤:
 

1) 未使用設置器

-(void) reset{

NSString *newName = [[NSString alloc]

initWithFormat:@”theNew”]; name = newName;

[newName release]; }

 

2)內存洩露

 

-(void) reset{

NSString *newName = [[NSString alloc]

initWithFormat:@”theNew”];

[self setName:newName];

}

 

3) 釋放沒有所有權的對象

-(void) reset{

NSString *newName = [NSString

stringWithFormat:@”theNew”];

[self setName:newName];

[newName release];

}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved