autorelease的使用和注意

原创 2015年07月08日 23:12:16

1.当我们创建一个对象时,(1)Person *p = [[Person alloc] init],就需要在下方执行一次(2)[p release],而[p release]一般放在最后,如果紧跟(1)的话,当创建完对象,对象就会被销毁,成为僵尸对象,假设,Person中有age属性,则再执行(3)p.age = 10;无疑会报错(野指针错误),如果放在程序的最后面的话,则p.age 正常执行。所以我们会担心(2)的乱放会造成许多错误。

例如:



解决方法是使用autorelease方法,其返回值是对象本身,autorelease会将对象放在一个自动释放池中,当自动释放池被销毁时,会对池子里面的所有对象做一次release操作所以代码:(1)Person *p = [[Person alloc] init],(4) [p autorelease].

 (1)(4)-> Person *p = [[[Person alloc] init]autorelease];

 

整体代码如下:



图示如下:



自动释放池销毁后:


注意:autorelease只是把对象扔到自动释放池里面(延迟了对象被销毁的时间),并不可以改变对象的计数器。改变计数器只有retain和release两种方法。缺点是:不能精确控制对象被销毁的时间,内存处理效率低(适用于占用内存比较小的对象,对象里面包含的属性主要是基本数据类型)。且autoreleasepool的存在是以栈结构存在的,栈结构的特点就是先进后出。当一个对象调用autorelease方法时,会将当前对象放到栈顶的释放池中。

 



autorelease和release不能同时适用。下面就是一个错误的使用:

autoreleasepool{

      Car *c = [[[Car alloc] init] autorelease];

 

      [c release];

     

}//野指针错误(message send to deallocted instance),当执行到这行代码时 c的计数器已经为0,但是释放池销毁,里面的对象需要再做一次release操作。(//或者 Car *c =[ [[[Car alloc] init] autorelease]autorelease];也是一个野指针错误)

 

 

2.ios 5.0版本以前:

自动是释放池的创建

NSAutoreleasePool*pool = [[NSAutoreleasePool alloc] init];

//对象代码区

[pool  release];//销毁池子

或者[pool drain]//已经被淘汰

 

 ios 5.0以后版本:

@autoreleasepool {

           //

           //

}

 

3.

1)Car *c = [[[Car alloc] init] autorelease];

如果要直接使用这句来创建对象的话,对于开发者,会觉得很浪费时间。所以如何优化这句代码呢?在开发过程中,我们会使用类方法,返回一个autorelease的对象。类方法返回对象类型(id)或(instancetype)。所以类方法如下:

 

+(instancetype)car{

 

      return [[[Car alloc] init] autorelease];

}

 

创建对象时就可以

//返回一个调用autorelease方法的Car对象c

Car *c = [Carcar];

 

如果我们想要一个直接返回对速度赋初值的Car对象

 

则可以这样:

//这只是个类方法并不是构造方法

+(instancetype)car{

Car * c = [[[Caralloc] init] autorelease];

c.speed = 100;

 

      return c ;

}

 

 

NSSting *str =@”1233”;

NSSting *str=[NSStringstringWithFormat:@”ha %d”,age ];

 

 

注意:系统自带方法里面如果没有包含alloc new 或者copy,说明返回的对象都是autorelease的。

规范:类方法的方法名一般以类名开头。类名相同的时候一般加前缀。

 

2)在开发过程中,如果父类有一个类方法可以快速创建一个调用autorelease方法的对象,在写类方法时,里面创建对象时我们要用self([[[self alloc] init] autorelease]),这样的话子类就不用重写这个方法来获取一个autorelease的对象。谁调用这个类方法,self则代表的就是谁。



autorelease深度理解

Autorelease机制是iOS开发者管理对象内存的好伙伴,MRC中,调用[obj autorelease]来延迟内存的释放是一件简单自然的事,ARC下,我们甚至可以完全不知道Autorelease...
  • allanGold
  • allanGold
  • 2016年06月14日 17:12
  • 949

OC语言之autorelease基本使用

# autorelease基本使用 ##1.autorelease基本概念 - autorelease是一种支持引用计数的内存管理方式,只要给对象发送一条autorelease消息,会将对象放到一个自...
  • u012938194
  • u012938194
  • 2016年02月21日 20:58
  • 677

ios学习--Objective C内存管理进阶(二):理解autorelease

如果你能够真正的理解autorelease,那么你才是理解了Objective c的内存管理。Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是...
  • yanfangjin
  • yanfangjin
  • 2012年05月08日 12:11
  • 12022

iOS内存管理之:引用计数、ARC、自动释放池autoreleasepool和便捷方法之间的关系

引用计数 Cocoa采用了引用计数(reference counting)机制,每一个对象有一个关联的“整数retainCount”用于记录对象的使用情况。对象被引用时retaincount+1...
  • cloudywend0207
  • cloudywend0207
  • 2016年02月25日 09:41
  • 1336

alloc、retain、copy、new、autorelease的区别

内存管理法则: 1.凡是用alloc,retain,new,copy,mutableCopy或者以copy开头,以mutableCopy开头的方法[创建]的对象,都需要用release或auto...
  • u010165653
  • u010165653
  • 2014年11月11日 18:44
  • 813

OC-retain,copy,assign及autorelease

一,retain, copy, assign区别 1. 假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了...
  • OnthewayH
  • OnthewayH
  • 2015年11月18日 10:23
  • 160

autorelease 的基本使用

3-循环的retain 问题人有宠物:狗 狗有主人:人 那么使用 #import 就会有问题,需要使用 @class 内存泄露的另一种情况 解决办法, 其中一个先释放(但是还有僵尸对象的问...
  • wanghy_ios
  • wanghy_ios
  • 2015年08月22日 15:43
  • 462

autorelease的使用场景

autorelease是解决函数返回值引用计数问题的一种方式。考虑这样一个场景,我们有个方法返回一个对象,在方法内部我们retain了这个对象,这意味这我们需要release这个对象,维持对象引用计数...
  • fly1183989782
  • fly1183989782
  • 2017年05月07日 13:50
  • 159

objective-c中@autoreleasepool的用法

objc中关于自动释放池,有两种语法,一种old-fashioned是:NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; //do...
  • mydo
  • mydo
  • 2015年05月21日 12:34
  • 2226

autorelease的使用和注意

1.当我们创建一个对象时,(1)Person *p = [[Person alloc] init],就需要在下方执行一次(2)[p release],而[p release]一般放在最后,如果紧跟(1...
  • miaopf123
  • miaopf123
  • 2015年07月08日 23:12
  • 1913
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:autorelease的使用和注意
举报原因:
原因补充:

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