国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

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

2019-11-14 19:50:55
字體:
來源:轉載
供稿:網友

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

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

 

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

 

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

 

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

 

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

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

 

 

(miki西游 @mikixiyou 原文 鏈接: http://mikixiyou.VEvb.com/blog/1592958 )

 

     測試方法如下:

 

     在 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=[[ NSMutableString alloc ] initWithString : @"mlgb" ];

    NSMutableString * mstr3;

    NSMutableString * mstr4=[[ NSMutableString alloc ] 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 ;

 

}

 

 

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 潮安县| 阆中市| 平度市| 弋阳县| 梅河口市| 漾濞| 隆尧县| 句容市| 江孜县| 班玛县| 元江| 建水县| 汝城县| 阳原县| 丹凤县| 甘洛县| 平凉市| 喜德县| 武川县| 大姚县| 武冈市| 澳门| 聂拉木县| 治多县| 锡林郭勒盟| 牟定县| 德格县| 潮州市| 巨鹿县| 桃园市| 湾仔区| 兴山县| 桐乡市| 土默特右旗| 宁波市| 龙胜| 黑龙江省| 九江市| 郧西县| 安福县| 烟台市|