苹果如何实现 autorelease

autorelease是苹果引以为傲的地方,它为程序开发人员减轻了很大的开发压力,下面就介绍下autorelease。

autorelease ,顾名思义,就是自动释放,它看上去就像是ARC,其实他更像C语言里面的自动变量(局部变量),

C语言里面的局部变量,就是当变量超出其作用域以后,该自动变量就会被自动抛弃。下面复习下C语言里面的自动变量

-(void)getIt

{

   int a =0;

   /*

     *因为超出变量作用域,

     *自动变量“int a”被废弃,不可再访问

     */

}


audiorelease会像C语言里面对待自动变量那样,对待实例对象,当超出其作用域的时候,对象实例的release方法就会被调用,同自动变量不同的是,对象的作用域可以右程序开发人员自己设定。

autorelease的具体使用方法是:1)、生成并持有NSAutoReseasePool对象。2)、调用已分配对象的autorelease实例方法。3)、废弃NSAutoReseasePool对象

-(void)objcAutorelease

{

    NSAutoreleasePool * autoreleasePool = [[NSAutoreleasePoolalloc]init];

   id objc = [[NSObjectalloc]init];

    [objcautorelease];

    [autoreleasePooldrain];

   /*

     *[autoreleasePool drain] 相当于 [objc release];

     *自动释放池[autoreleasePool drain]的时候,会给池子里面的对象发送一个release消息,让实例变量执行release方法

     */


}


其实需要注意的是,如果大量对象autorelease,只要NSAutoreleasePool没有被废弃,那么生成的对象就不能被释放,就会导致内存不足,典型的例子是读入大量的图片,并且改变图片的尺寸,图像文件读入到NSData对象,并从中生成UIImage对象,这种情况会产生大量的autorelease对象,


for (int i =0; i<10000; i++) {

       /*

         *读入大量图像10000

         *由于没有废弃NSAutoreleasePool对象

         *最终导致内存不足

         */

}


所以可以看出上面的理智是有问题的,所以我们需要在适当的位置,生成、持有、废弃NSAutoreleasePool对象

for (int i =0; i<10000; i++) {

       NSAutoreleasePool * autoreleasePool = [[NSAutoreleasePoolalloc]init];

        

       /*

         *读入大量图像

         *由于没有废弃NSAutoreleasePool对象

         *最终导致内存不足

         */

        [autoreleasePooldrain];

       /*

         *通过[autoreleasePool drain];

         *autorelease对象被一起release

         */   

}


其实在cocoa中,有很多类方法返回autorelease对象,比如说

NSArray * arr1 = [NSArrayarray];//里面已经存在autorelease

NSArray * arr2 = [[[NSArrayalloc]init]autorelease];

    

NSMutableArray * mutableArr1 = [NSMutableArrayarrayWithCapacity:2];

NSMutableArray *mutableArr2 = [[[NSMutableArrayalloc]initWithCapacity:2]autorelease];


arr1 和arr2 mutableArr1和mutableArr1都是一个道理。

其实autorelease的实现,我们可以追溯到源代码

id  obj  = [[NSObjectalloc]init];

[obj autorelease];

其实obj内部实现应该是如下方式

-(void)autorelease

{

    [NSAutoreleasePooladdObject:self];

}

autorelease的实质方法的本质就是调用了 NSAutoreleasePool对象的 addObject的类方法


那到底苹果自己是如何处理NSAutoreleasePool的呢?它的内部实现应该是怎么样的呢,我们可以简单的如下猜想

NSAutoreleasePool调用的addObject方法如下:


+(void)addObject:(id)anObject

{

    NSAutoreleasePool * autoreleasePool =//取得正在使用NSAutoreleasePool的对象;

   if (autoreleasePool) {

        [autoreleasePool addObject:anObject];

    }else{

        //对象非存在状态下调用autorelease

    }

}

然后是 NSAutoreleasePool 对象autoreleasePool调用 addObject:方法,此时被autorelease的该对象,将会被添加到正在使用的NSAutoreleasePool里面

NSAutoreleasePool的对象能不能autorelease呢?

答案是不能的,如果你调用

[autoreleasePoolautorelease];就会出现异常

控制台你会看到

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSAutoreleasePool autorelease]: Cannot autorelease an autorelease pool'





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值