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

news/2024/7/20 15:43:37 标签: 内存管理, xcode, 数据结构与算法

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

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

 

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

 

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

 

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

 

   事实上,引用计数是对内存区域的空间管理方式,是应从内存块的视角去看的。

不论什么对象都是指向它的指针,有多少个指针指向它。就有多少个引用计算。

   假设没有不论什么指针指向该内存块了。非常明显,该内存块就没有对象引用了。引用计算就是 0, 系统会人为该内存区域已经空暇。于是马上清理。也就是更新一下管理堆的链表中某个标示位。

 

 

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

 

     測试方法例如以下:

 

     xcode 中建立一个非 arc 的项目。单视图就可以。建立一个button的操作方法。

 

     - (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+ ;

 

}

转载于:https://www.cnblogs.com/jzdwajue/p/7067029.html


http://www.niftyadmin.cn/n/914645.html

相关文章

Fedora 怎样设置终端快捷键

http://jingyan.baidu.com/article/cb5d61053598ed005d2fe05c.html

Mybatis错误:Parameter 'XXX' not found. Available parameters are [1, 0, param1, param2]

Select("select * from fruitsell where f_id#{f_id} and u_id#{u_id}") public Fruitsell finbyfruitsell(Long f_id,Long u_id); 正确代码如下: Select("select * from fruitsell where f_id#{f_id} and u_id#{u_id}") public Frui…

C语言 调用的动态库函数重名问题分析

设计两个动态库 第一个动态库:libHelloc: func1.h #ifndef FUNC1_H_ #define FUNC1_H_int func1(); void func();#endiffunc1.c #include "func1.h"int func1() {return 0; }void func() {printf("func at libHelloc\n");printf("invode…

离散数学实验1

一个离散数学的实验&#xff1a;已知一个无向图&#xff0c;求出这个无向图的割边/桥&#xff0c;所有的边割集。 这是初始的定义和头文件 #include <stdio.h> #include <string.h> #include<malloc.h> #define INFINITY 100 #define MAX_VERTEX_NUM 20 …

linux 反汇编分析变量地址并用gdb修改运行中的程序内存变量实验

准备样本文件&#xff1a; a.c #include <stdio.h> #include <unistd.h>unsigned int a0xFFFFFFFF; unsigned int b0xEEEEEEEE;void main(){while(1){printf("%x, %x\n", a, b);sleep(1);} }编译可执行程序&#xff1a;gcc -g a.c运行a.out输出:$ ./a.o…

JsonArray和JsonObject遍历方法

一&#xff1a;遍历JsonArray // 一个未转化的字符串 String str "[{name:a,value:aa},{name:b,value:bb},{name:c,value:cc},{name:d,value:dd}]" ; // 首先把字符串转成 JSONArray 对象 JSONArray json JSONArray.fromObject(str ); if(json.size()>0){ …

linux 反汇编分析变量地址,直接修改二进制文件中变量值

样本文件准备及变量地址分析参考 http://blog.csdn.net/hknaruto/article/details/51097902 1. 根据上述记录过程得到进程启动后变量a地址为&#xff1a;0x60103c 2. bvi 打开文件,发现文件根本没有这么长&#xff0c;最末尾数据如下 00002590 00 00 00 00 00 00 00 00 B0 …

交换机的工作模式:IVL和SVL

IVL&#xff08;independent vlan learning&#xff09;每个vlan建一个表&#xff0c;看起来好像有很多表&#xff0c;其实这里所说的表是指逻辑上的表&#xff0c;实际上在交换机中还是只有一个表。如果将VID相同的记 录都提取出来组成一个表&#xff0c;那么一个物理上的表在…