Object-C语法之内存管理

转载 2013年12月02日 14:13:57

1、Objective-C内存管理简介:

    Objective-C需要自己考虑内存的管理,对于从Java, C#等语言转向Objective-C平台的程序员新手来说,这是个很大的挑战。幸运的是,如果熟悉了Objective-C的内存管理机制,手工管理内存也没有那么可怕。 Objective-C的内存管理介于C/C++和Java C#直接,不像C/C++语言内存管理全部需要程序员一手包办,也不像Java C#语言有那么完备的内存垃圾回收器。(Objective-C 2.0有GC机制,不过不支持IOS)。那他是怎么管理内存的呢?通过引用计数进行管理的。PS:在iOS 5后增加了Automatic Reference Counting(ARC 自动引用计数)特性,这样程序员不需要自己操心管理内存了,ARC和GC不一样,ARC是编译器的行为。ARC后面再讲。不过熟悉Objective-C的内存管理机制是非常必要的。

2、内存管理原理:

   Objective-C内存管理模型是基于对象的所有权。如果你拥有这个对象,那么你就有责任去释放它。一个对象可以有多个拥有者。如果这个对象的拥有和为0时,系统将自动释放这个对象。对象的所有权和释放有四个原则:

  • 任何你创建的对象你都获得其所有权。(包括 alloc ,new ,copy等关键字获得的对象)
  • 通过retain获得对象的所有权
  • 如果你不需要一个对象了,你必须释放所有权
  • 你不能释放你没有所有权的对象
引用计数(retainCount)是Objective-C对象引用的唯一依据。调用实例管理的release方法后,此属性减1,减到为零时对象的dealloc方法被自动调用,进行内存回收操作,也就是说我们永不该手动调用对象的dealloc方法。

图片来自苹果官网。

3、示例:环境是在不选择ARC的环境下

新建Person类,使他继承与NSObject,在.m文件中实现dealloc方法:
  1. - (void) dealloc    
  2. {    
  3.     NSLog (@"dealloc called. Bye Bye.");    
  4.     [super dealloc];    
  5.       
  6. }   
在引用计数为0时,这个方法就会被调用,证明这个对象被销毁。

创建一个对象,打印它的引用计数
  1. Person *person = [[Person alloc] init];  
  2.   
  3. NSLog(@"对象person的retainCount: %d", [person retainCount]);  

对象personretainCount: 1

我们增加1

  1. Person *person = [[Person alloc] init];  
  2.  NSLog(@"对象person的retainCount: %d",[person retainCount] );  
  3.  [person retain];  
  4.  NSLog(@"对象person的retainCount: %d", [person retainCount]);  

打印结果:

对象personretainCount: 1

对象personretainCount: 2

和传说的一样,retainCount增加了。可以有在release时,减少到1时就不再减 了

  1. Person *person = [[Person alloc] init];  
  2. NSLog(@"对象person的retainCount: %d",[person retainCount] );  
  3. [person retain];  
  4. NSLog(@"对象person的retainCount: %d", [person retainCount]);  
  5. [person release];  
  6. [person release];  
  7. NSLog(@"对象person的retainCount: %d", [person retainCount]);  
这个代码最后打印出来的retainCount是0吗?打印结果:
  1. 2012-07-05 16:05:29.830 ObjectiveCTest[2847:f803] 对象person的retainCount: 1  
  2. 2012-07-05 16:05:29.831 ObjectiveCTest[2847:f803] 对象person的retainCount: 2  
  3. 2012-07-05 16:05:29.831 ObjectiveCTest[2847:f803] dealloc called. Bye Bye.  
  4. 2012-07-05 16:05:29.832 ObjectiveCTest[2847:f803] 对象person的retainCount: 1  
震惊了,第一次release 时retainCount减1了,再release , d对象的dealloc called了,但是retainCount 还是1.在stackoverflow.com的查了一下,有人说这个retainCount没什么用。。。。可以事实的确如retainCount是1,对象被干掉了。有人说,要把person = nil。这样retainCount就是0了。试了下,nil的 retainlCount永远是0.这个赋值没有意义。

4、NSAutoreleasePool自动释放内存

如果仅仅是创建,释放,这样对应,就很好理解。但是大多数人不理解的是自动释放内存这个地方,感觉琢磨不透,但其实原理也很简单。
C/C++编程时有个很重要的对内存管理的原则:谁创建谁销毁。但是这个原则在有些情况下却无法遵守:比如让一个普通函数返回一块内存区域。函数调用者必须在函数调用完毕后自己负责销毁这块内存,而在Objective-C的自动内存释放的机制下,就不用那么烦恼了。

先看看最经典的程序入口程序,也用到自动释放。

  1. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
  2. int retVal = UIApplicationMain(argc, argv, nil, nil);  
  3. [pool release];  
我们先把pool看成一个普通对象,先是alloc,pool的retainCount为1。
第三句release,retainCount为0,自动调用它的dealloc方法。它和任何其它普通对象没 任何区别。
神奇的地方在哪里?
NSAutoreleasePool内部包含一个数组(NSMutableArray),用来保存声明为autorelease的所有对象。如果一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中去。NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数组,release数组中的每个成员。如果此时数组中成员的retain count为1,那么release之后,retain count为0,

  1. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
  2. Person *person = [[Person alloc] init];  
  3. NSLog(@"对象person的retainCount: %d",[person retainCount] );  
  4. [person autorelease];  
  5. NSLog(@"到这里,person还没被释放");  
  6. [pool release];  

打印结果:

  1. 2012-07-05 16:34:38.823 ObjectiveCTest[3045:f803] 对象person的retainCount: 1  
  2. 2012-07-05 16:34:38.823 ObjectiveCTest[3045:f803] 到这里,person还没被释放  
  3. 2012-07-05 16:34:38.824 ObjectiveCTest[3045:f803] dealloc called. Bye Bye.  
在调用pool release的时候,person才被释放。这就是自动释放的神奇的地方,这样就可以创建对象

著作权声明:本文由http://blog.csdn.net/totogo2010/原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!


Object-c学习之路二(oc内存管理黄金法则1)

今天看了看oc的内存管理,自己管理内存不能随便的release和retain 法则会出现野指针等错误。下面以人和读书的例子做练习。 1.主函数 // // main.m // MemoryMa...

Object-C详细编程教(五)-手动内存管理

有效的管理内存 1.内存分配:当程序创建对象时需要为对象分配内存。采用合理的设计,尽量减少对象的创建,并减少对创建过程中内存的开销,这是内存管理一方面的。 2.内存回收:当程序不再需要对象时,系统...

OBject-C 学习笔记之内存管理

OBject-C 学习笔记之内存管理 基本原理:     1、内存管理         1.1移动设备的内存极其有限,每个app所能占用的内存是有限制的         1.2当app...

Object-C内存管理中的黄金法则

在Object-C中,内存的管理是通过retain和release来对对象的计数器进行加1或者减1来进行管理,当使用一个对象 的时候需要进行对对象的计数器加1,使用完成后要减1进行释放,当计数器等于...

Object-C连载九----内存管理

一.什么是内存管理   OC中的内存管理只针对OC中的对象,所有的对象都继承NSObject,都是一小块内存指向一大块内存   基本数据类型不需管理内存int,float,char,double,...
  • Wing_n
  • Wing_n
  • 2015年08月10日 08:40
  • 249

ios学习--Object-C中的内存管理

免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何纠纷,均与本博客所有人、发表该翻译稿之人无任何关系。谢谢合作...

Object-c内存管理精髓

iPhone系统中的Objective-C的内存管理机制是比较灵活的,即可以拿来像C/C++一样用,也可以加个AutoreleasePool让它升级为半自动化的内存管理语言。当然,也不能拿JAVA虚拟...

黑马程序员-IOS开发之--Object-c-- 内存管理二

---------------------- http://www.itheima.com"target="blank">ASP.Net+Unity开发、.Net培训、期待与您交流! ------...

20160812Object-c关于内存管理一

前言:内存管理是个重要的概念,经历了几次面试,这个是考察的重点,的确要想用一门语言写出使用效率高而且没有bug的代码,就得掌握其内存管理模型的种种细节。 OC使用引用计数来管理内存,每个对象都有...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Object-C语法之内存管理
举报原因:
原因补充:

(最多只允许输入30个字)