Objective-C语法之内存管理

网友投稿 236 2022-11-28

Objective-C语法之内存管理

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

在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方法:

[cpp]  ​​view plain​​​ ​​copy​​

- (void) dealloc{"dealloc called. Bye Bye.");[super dealloc];}

在引用计数为0时,这个方法就会被调用,证明这个对象被销毁。

创建一个对象,打印它的引用计数

[cpp]  ​​view plain​​​ ​​copy​​

Person *person = [[Person alloc] init];NSLog(@"对象person的retainCount: %d", [person retainCount]);

对象person的retainCount: 1

我们增加1

[cpp]  ​​view plain​​​ ​​copy​​

Person *person = [[Person alloc] init];"对象person的retainCount: %d",[person retainCount] );[person retain];"对象person的retainCount: %d", [person retainCount]);

打印结果:

对象person的retainCount: 1

对象person的retainCount: 2

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

[cpp]  ​​view plain​​​ ​​copy​​

Person *person = [[Person alloc] init];NSLog(@"对象person的retainCount: %d",[person retainCount] );[person retain];NSLog(@"对象person的retainCount: %d", [person retainCount]);[person release];[person release];NSLog(@"对象person的retainCount: %d", [person retainCount]);

这个代码最后打印出来的retainCount是0吗?打印结果:

[cpp]  ​​view plain​​​ ​​copy​​

2012-07-05 16:05:29.830 ObjectiveCTest[2847:f803] 对象person的retainCount: 12012-07-05 16:05:29.831 ObjectiveCTest[2847:f803] 对象person的retainCount: 22012-07-05 16:05:29.831 ObjectiveCTest[2847:f803] dealloc called. Bye Bye.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的自动内存释放的机制下,就不用那么烦恼了。

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

[cpp]  ​​view plain​​​ ​​copy​​

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];int retVal = UIApplicationMain(argc, argv, nil, nil);[pool release];

[cpp]  ​​view plain​​​ ​​copy​​

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

打印结果:

[cpp]  ​​view plain​​​ ​​copy​​

2012-07-05 16:34:38.823 ObjectiveCTest[3045:f803] 对象person的retainCount: 12012-07-05 16:34:38.823 ObjectiveCTest[3045:f803] 到这里,person还没被释放2012-07-05 16:34:38.824 ObjectiveCTest[3045:f803] dealloc called. Bye Bye.

在调用pool release的时候,person才被释放。这就是自动释放的神奇的地方,这样就可以创建对象

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:USB Type-C将彻底解决用户面临连接梦靥
下一篇:在拦截器中读取request参数,解决在controller中无法二次读取的问题
相关文章

 发表评论

暂时没有评论,来抢沙发吧~