`
mikixiyou
  • 浏览: 1086733 次
  • 性别: Icon_minigender_1
  • 来自: 南京
博客专栏
C3c8d188-c0ab-3396-821d-b68331e21226
Oracle管理和开发
浏览量:349534
社区版块
存档分类
最新评论

iOS中引用计数内存管理机制分析

    博客分类:
  • iOS
阅读更多


    iOS 中引用计数是内存的管理方式,虽然在 iOS5 版本中,已经支持了自动引用计数管理模式,但理解它的运行方式有助于我们了解程序的运行原理,有助于 debug 程序。

   操作系统的内存管理分成堆和栈。


   在堆中分配的内存,都试用引用计数模式;在栈中则不是。


   NSString 定义的对象是保存在栈中,所以它没有引用计算。看一些书上说它的引用计算会是 fffffffff 最大整数,测试的结果显示它是- 1. 对该对象进行 retain 操作,不好改变它的 retainCount 值。


   MutableNSString 定义的对象,需要先分配堆中的内存空间,再初始化才能使用。它是采用引用计数管理内存的。对该对象做 retainCount 操作则每次增加一个。


   其实,引用计数是对内存区域的空间管理方式,是应从内存块的视角去看的。任何对象都是指向它的指针,有多少个指针指向它,就有多少个引用计算。

   如果没有任何指针指向该内存块了,很明显,该内存块就没有对象引用了,引用计算就是 0, 系统会人为该内存区域已经空闲,于是立即清理,也就是更新一下管理堆的链表中某个标示位。



(miki西游 @mikixiyou 原文 链接: http://mikixiyou.iteye.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 ;


}



简而言之,引用计数实际上是指向其内存区域的指针数,从内存块的角度去理解,就很容易理解了。


0
0
分享到:
评论

相关推荐

    iOS 内存管理机制 详细解读

    5.1)Objective-C内存管理相关术语 5.2)什么是引用计数? 5.2.1)引用计数解释 5.2.2)文艺解释 5.2.3)代码测试 5.3)自动释放池 5.3.1)AutoreleasePool的原理 5.3.2)自动释放池的创建和销毁 5.3.3)自动释放池的使用...

    iOS/OSX内存管理(二):借助工具解决内存问题

    上一篇博客《iOS/OSX内存管理(一):基本概念与原理》主要讲了iOS/OSX内存管理中引用计数和内存管理规则,以及引入ARC新的内存管理机制之后如何选择ownershipqualifiers(__strong、__weak、__unsafe_unretained和__...

    iOS内存管理方面的面试题汇总

    如何检测内存泄漏? 如何解决循环引用? 悬垂指针?野指针? 对 retain,copy,assign,weak,_Unsafe_Unretain 关键字的理解;...自动引用计数应遵循的原则; Dealloc 的实现机制; 内存管理方案 ... ... ...

    ios开发技巧总结.docx

    ios开发 iOS开发涵盖了许多方面,以下是一些关键的开发技巧和最佳实践: 熟悉Swift或Objective-C:Swift是苹果...内存管理:理解ARC(Automatic Reference Counting)自动引用计数机制,避免内存泄漏和循环引用问题。

    Object C 内存管理

    Object C 内存管理课件,关于一些内存管理机制 还有手动内存 引用计数操作的一些 小例子

    iOS开发系列-ARC浅解

    ARC机制的引入是为了简化开发过程的内存管理的。相对于之前的MRC (Manual Reference Counting) , ARC机制显得更加自动化。在使用ARC开发过程中,开发者只需考虑strong / weak 的使用,不再需要考虑对象何时要retain...

    Swift语言教程.docx

    内存管理:Swift 使用自动引用计数(ARC)机制管理内存,开发者无需手动管理内存分配与释放,减少了内存泄漏和悬垂指针等问题。 现代编程特性:支持泛型、协议、扩展、闭包、枚举(包括关联值和递归枚举)、可选...

    Swift应用领域以及对开发者和移动应用开发

    2. 安全性:Swift在安全性方面下了很大功夫,通过类型检查、空值处理和内存管理等机制,避免了许多常见的编程错误。它还采用了安全的编程风格,并强制执行访问控制。 3. 高性能:Swift经过优化,能够提供与...

    Cocos2D-X游戏开发技术精解

    7.7.2 内存管理机制 207 7.7.3 工厂模式 208 7.7.4 数据单位 208 7.7.5 用户数据 209 7.8 物理世界World 210 7.8.1 创建和摧毁一个世界 210 7.8.2 让世界运转起来 211 7.8.3 探索世界 212 7.8.5 AABB查询 213 7.8.6 ...

Global site tag (gtag.js) - Google Analytics