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

                                                                ------ Java培训、Android培训、iOS培训、.Net培训 、期待与您交流! -------

autorelease基本使用

1、自动释放池及autorelease介绍

自动释放池

(1)在iOS程序运行过程中,会创建无数个池子,这些池子都是以栈结构(先进后出)存在的。

(2)当一个对象调用autorelease时,会将这个对象放到位于栈顶的释放池中 

(1)iOS 5.0以前的创建方式

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

`````````````````

[pool release];//[pool drain];用于mac 

(2)iOS5.0以后

@autoreleasepool

{//开始代表创建自动释放池

   ·······   

}//结束代表销毁自动释放池 

autorelease

是一种支持引用计数的内存管理方式

它可以暂时的保存某个对象(object),然后在内存池自己的排干(drain)的时候对其中的每个对象发送release消息

注意,这里只是发送release消息,如果当时的引用计数(reference-counted)依然不为0,则该对象依然不会被释放。可以用该方法来保存某个对象,也要注意保存之后要释放该对象。

2、为什么会有autorelease?

OC的内存管理机制中比较重要的一条规律是:谁申请,谁释放。

考虑这种情况,如果一个方法需要返回一个新建的对象,该对象何时释放?

方法内部是不会写release来释放对象的,因为这样做会将对象立即释放而返回一个空对象;调用者也不会主动释放该对象的,因为调用者遵循“谁申请,谁释放”的原则。那么这个时候,就发生了内存泄露。

这就是不使用autorelease存在的问题

针对这种情况,Objective-C的设计了autorelease,既能确保对象能正确释放,又能返回有效的对象

使用autorelease的好处

(1)不需要再关心对象释放的时间

(2)不需要再关心什么时候调用release

3、autorelease基本用法

基本用法

(1)会将对象放到一个自动释放池中

(2)当自动释放池被销毁时,会对池子里的所有对象做一次release

(3)会返回对象本身

(4)调用完autorelease方法后,对象的计数器不受影响(销毁时影响)

在autorelease的模式下,下述方法是合理的,即可以正确返回结果,也不会造成内存泄露

ClassA*Func1()

{

   ClassA *obj = [[[ClassA alloc]init]autorelease];

   return obj;

}  

4、autorelease是什么原理?

    autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autoreleasepool中,当该pool被释放时,该pool中的所有Object会被调用 Release。

5、autorelease何时释放?

    对于autoreleasepool本身,会在如下两个条件发生时候被释放(详细信息请参见第5条)

1)手动释放Autoreleasepool

2)Runloop结束后自动释放

对于autoreleasepool内部的对象

在引用计数的retain ==0的时候释放。release和autorelease pool 的 drain都会触发retain-- 事件。

6、autorelease释放的具体原理是什么?

要搞懂具体原理,则要先搞清楚autorelease何时会创建。

我们的程序在main()调用的时候会自动调用一个autorelease,然后在每一个Runloop,系统会隐式创建一个Autorelease pool,这样所有的releasepool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的 Autoreleasepool(main()里的autorelease)会被销毁,这样这个pool里的每个Object会被release。

可以把autoreleasepool理解成一个类似父类与子类的关系,main()创建了父类,每个Runloop自动生成的或者开发者自定义的autoreleasepool都会成为该父类的子类。当父类被释放的时候, 没有被释放的子类也会被释放,这样所有子类中的对象也会收到release消息。那什么是一个Runloop呢? 一个UI事件,Timer call, delegate call, 一个鼠标事件,键盘按 下(MACOSX),或者iphone上的触摸事件,异步http连接下后当接收完数据时,都会是一个新的 Runloop。一般来说,消息循环运行一次是毫秒级甚至微秒级的,因此autorelease的效率仍然是非常高的, 确实是一个巧妙的设计。 

对象调用autorelease方法,自己的引用计数并没有减一,它只是将对象放到了一个池子中。池子销毁时,只会对它里面的对象做一次release操作。

池子也是以压栈的方式在内存中存储的。 

苹果官方提供的方法(API

1,如果方法名不是alloc,new,就不用release或者autorelease;

2,如果方法名是alloc,new,就必须release或者autorelease。

<span style="font-size:14px;">#import <Foundation/Foundation.h>
@interface Person : NSObject
-(void)run;
@end
@implementation Person
- (void)dealloc
{
    NSLog(@"Person dealloc");
    [super dealloc];
}
-(void)run{   
    NSLog(@"人在跑");   
}
@end
int main(int argc, const char * argv[]) {
    //1 创建自动释放池
    Person *p = [Person new];  // p  1
    @autoreleasepool {//自动释放池开始        
        [p run];        
        NSLog(@"%lu",p.retainCount); // 1        
        // [p autorelease] 把对象p加入到自动释放池中
        // 注意:加入到自动释放池中以后, 引用计数不会变化
        [p autorelease];  //加入自动释放池,
        NSLog(@"%lu",p.retainCount); // 1        
        [p run];       
    }//自动释放池结束   [p release];
    [p run];
    return 0;
}</span>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值