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...

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

如果你能够真正的理解autorelease,那么你才是理解了Objective c的内存管理。Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是...

Object-C基础(5)——指针

要接受的观点     1.操作系统管理内存分配(有人来了,要分房间给它住)、内存回收(人走了,房间要收回来)的方式就是给内存编号。这个编号是二进制的编号,而且与操作系统位数相关。     2.  所有...

Cocoa菜单栏右侧图标的实现

与Windows中的Tray Icon不同,Mac OS X中类似的UI元素位于屏幕右上角菜单栏的右侧,官方命名为Status Item,我们可以使用NSStatusBar和NSStatusItem类...
  • czl0325
  • czl0325
  • 2014年12月12日 14:00
  • 642

90-自动释放池 autorelease经典案例题原理,创建和销毁,经典案例题,注意问题

自动释放池 autorelease    1.自动释放池原理 1>所有 autorelease的对象,在出了作用域之后,会被添加到 最近 创建的自动释放池中 2>当自动释放池被耗尽或者销毁时,...

苹果官方文档:使用Autorelease Pools

翻译自: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmA...

Objective-C 【autorelease基本使用】

——————————————————————————————————————————— NSString中的内存管理问题 由于autoreleasepool的存在,对于内存管理就会很复杂,retai...

OC语言之autorelease基本使用

# autorelease基本使用 ##1.autorelease基本概念 - autorelease是一种支持引用计数的内存管理方式,只要给对象发送一条autorelease消息,会将对象放到一个自...

黑马程序员——OC语言加强---autorelease基本使用

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- autorelease基本使用 1、自动释放池及autorelease介绍 自动释...

黑马程序员—OC基础—autorelease的使用

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 黑马程序员—OC基础—autorelease的使用 自动释放池: (1)在iOS程...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:autorelease的使用和注意
举报原因:
原因补充:

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