关闭

autorelease的使用和注意

标签: autorelease自动释放池releaseios指针
1244人阅读 评论(0) 收藏 举报
分类:

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则代表的就是谁。



1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:36264次
    • 积分:852
    • 等级:
    • 排名:千里之外
    • 原创:51篇
    • 转载:0篇
    • 译文:1篇
    • 评论:10条
    最新评论