你好,歡迎來到IOS教程網

 Ios教程網 >> IOS使用技巧 >> IOS技巧綜合 >> iOS中引用計數內存管理機制分析

iOS中引用計數內存管理機制分析

編輯:IOS技巧綜合
[摘要]本文是對iOS中引用計數內存管理機制分析的講解,對學習IOS蘋果軟件開發有所幫助,與大家分享。

在iOS中引用計數是內存的管理方式,雖然在iOS5版本中,已經支持了自動引用計數管理模式,但理解它的運行方式有助於我們了解程序的運行原理,有助於debug程序。

操作系統的內存管理分成堆和棧。

在堆中分配的內存,都試用引用計數模式;在棧中則不是。

NSString定義的對象是保存在棧中,所以它沒有引用計算。看一些書上說它的引用計算會是fffffffff最大整數,測試的結果顯示它是-1.對該對象進行retain操作,不好改變它的retainCount值。

MutableNSString定義的對象,需要先分配堆中的內存空間,再初始化才能使用。它是采用引用計數管理內存的。對該對象做retainCount操作則每次增加一個。

其實,引用計數是對內存區域的空間管理方式,是應從內存塊的視角去看的。任何對象都是指向它的指針,有多少個指針指向它,就有多少個引用計算。

如果沒有任何指針指向該內存塊了,很明顯,該內存塊就沒有對象引用了,引用計算就是0,系統會人為該內存區域已經空閒,於是立即清理,也就是更新一下管理堆的鏈表中某個標示位。

測試方法如下:

在xcode中建立一個非arc的項目,單視圖即可。建立一個按鈕的操作方法。

- (IBAction)testRC:(id)sender {

NSInteger i;

i=self.i_test;

if((i%2)==1)

{

NSString * str1=@"welcome";

NSString * str2=@"mlgb";

NSString * str3;

NSString * str4=@"welcome";

NSLog(@"str1 addr is %p",str1);

NSLog(@"str2 addr is %p",str3);

NSLog(@"str3 addr is %p",str3);

NSLog(@"str4 addr is %p",str4);

NSLog(@"str1 retainCount is %i",[str1 retainCount]);

NSLog(@"str2 retainCount is %i",[str2 retainCount]);

//NSLog(@"str3 retainCount is %i",[str3 retainCount]);該使用會導致crash,因為str3沒有指向任何內存區域。

str3=[str1 retain];

NSLog(@"str3=[str1 retain];");

NSLog(@"str1 retainCount is %i",[str1 retainCount]);

NSLog(@"str3 retainCount is %i",[str3 retainCount]);

str3=[str2 retain];

NSLog(@"str3=[str2 retain];");

NSLog(@"str2 retainCount is %i",[str1 retainCount]);

NSLog(@"str3 retainCount is %i",[str2 retainCount]);

/*

結果如下:

2012-07-14 11:07:38.358 testMem[878:f803] str1 addr is 0x3540

2012-07-14 11:07:38.360 testMem[878:f803] str2 addr is 0x0

2012-07-14 11:07:38.361 testMem[878:f803] str3 addr is 0x0

2012-07-14 11:07:38.362 testMem[878:f803] str4 addr is 0x3540

在棧中,內容相同的對象str1和str4,都分配在一個內存區域中,這點是c編譯器的功能,有利於內存使用和效率。

2012-07-14 11:07:38.363 testMem[878:f803] str1 retainCount is -1

2012-07-14 11:07:38.364 testMem[878:f803] str2 retainCount is -1

2012-07-14 11:07:38.365 testMem[878:f803] str3=[str1 retain];

2012-07-14 11:07:38.366 testMem[878:f803] str1 retainCount is -1

2012-07-14 11:07:38.367 testMem[878:f803] str3 retainCount is -1

2012-07-14 11:07:38.367 testMem[878:f803] str3=[str2 retain];

2012-07-14 11:07:38.368 testMem[878:f803] str2 retainCount is -1

2012-07-14 11:07:38.369 testMem[878:f803] str3 retainCount is -1

*/

}

else

{

NSMutableString * mstr1=[[NSMutableString alloc] initWithString:@"welcome"];

NSMutableString* mstr2=[[NSMutableStringalloc]initWithString:@"mlgb"];

NSMutableString* mstr3;

NSMutableString* mstr4=[[NSMutableStringalloc]initWithString:@"welcome"];

NSLog(@"mstr1 addr is %p",mstr1);

NSLog(@"mstr2 addr is %p",mstr2);

NSLog(@"mstr3 addr is %p",mstr3);

NSLog(@"mstr4 addr is %p",mstr4);

NSLog(@"mstr1 retainCount is %i",[mstr1 retainCount]);

NSLog(@"mstr2 retainCount is %i",[mstr2 retainCount]);

//NSLog(@"mstr3 retainCount is %i",[mstr3 retainCount]);

mstr3=[mstr1 retain];

NSLog(@"mstr3=[mstr1 retain];");

NSLog(@"mstr1 retainCount is %i",[mstr1 retainCount]);

NSLog(@"mstr3 retainCount is %i",[mstr3 retainCount]);

NSLog(@"mstr3 addr is %p",mstr3);

mstr3=[mstr2 retain];

NSLog(@"mstr3=[mstr2 retain];");

NSLog(@"mstr2 retainCount is %i",[mstr1 retainCount]);

NSLog(@"mstr3 retainCount is %i",[mstr2 retainCount]);

NSLog(@"mstr3 addr is %p",mstr3);

/*

2012-07-14 11:07:36.652 testMem[878:f803] mstr1 addr is 0x68706b0

2012-07-14 11:07:36.655 testMem[878:f803] mstr2 addr is 0x6876040

2012-07-14 11:07:36.656 testMem[878:f803] mstr3 addr is 0x2a35

2012-07-14 11:07:36.657 testMem[878:f803] mstr4 addr is 0x686fbf0

2012-07-14 11:07:36.657 testMem[878:f803] mstr1 retainCount is 1

2012-07-14 11:07:36.658 testMem[878:f803] mstr2 retainCount is 1

2012-07-14 11:07:36.659 testMem[878:f803] mstr3=[mstr1 retain];

2012-07-14 11:07:36.660 testMem[878:f803] mstr1 retainCount is 2

2012-07-14 11:07:36.660 testMem[878:f803] mstr3 retainCount is 2

2012-07-14 11:07:36.661 testMem[878:f803] mstr3 addr is 0x68706b0

2012-07-14 11:07:36.662 testMem[878:f803] mstr3=[mstr2 retain];

2012-07-14 11:07:36.663 testMem[878:f803] mstr2 retainCount is 2

2012-07-14 11:07:36.663 testMem[878:f803] mstr3 retainCount is 2

2012-07-14 11:07:36.664 testMem[878:f803] mstr3 addr is 0x6876040

*/

}

self.i_test=self.i_test+1;

}

簡而言之,引用計數實際上是指向其內存區域的指針數,從內存塊的角度去理解,就很容易理解了。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved