首页 > 代码库 > iOS autorelease使用详解

iOS autorelease使用详解

1.作用

1.1 给对象发送一条autorelease消息, 会将对象放到一个自动释放池中
1.2 当自动释放池被销毁时,会对池子里面的所有对象做一次release操作
1.3 会返回对象本身
1.4 调用完autorelease方法后,对象的计数器不变
 
2.好处
2.1 不用再关心对象释放的时间,有利于规避坏内存访问的出现
2.2 不用再关心什么时候调用release
 
3. 使用注意
3.1 占用内存较大的对象不要随便使用autorelease
3.1 占用内存较小的对象使用autorelease,没有太大影响
 
4.autoreleasepool
autoreleasepool是以栈结构存储的,先进后出,只有栈顶的Pool才处于活动状态,才可以装对象.并且因为是栈结构,所以销毁,是先销毁栈顶的pool,最后是栈底.

示例代码:

@autoreleasepool { // 栈底的pool

  @autoreleasepool { // 中间的pool 

     @autoreleasepool { // 栈顶的pool.....还可以嵌套

        People *people = [[[People alloc] init] autorelease];

      }

   GoodPeople *goodpeople = [[[GoodPeople alloc] init] autorelease];   

  }

  BadPeople *badpeople = [[[BadPeople alloc] init] autorelease]; 

}

// People.m文件
- (void)dealloc{
  NSLog(@"人释放了");
  [super dealloc];
}
// GoodPeople.m文件
- (void)dealloc{
  NSLog(@"好人释放了");
  [super dealloc];
}
// BadPeople.m文件
- (void)dealloc{
  NSLog(@"坏人释放了");
  [super dealloc];
}
控制台的打印结果:
人释放了
好人释放了
坏人释放了
技术分享
5.自动释放池的创建方式
5.1 头尾式
5.2 花括号式
 
6.autorelease的常见错误
6.1 Person *p = [[[Person alloc] init] autorelease];

  [p release]; //这行代码一执行完,p就不存在了,等p所在的pool销毁时,会给p发送release消息,那时会报坏访问错误

6.2 Person *p = [[[[Person alloc] init] autorelease] autorelease]; //这行代码,表示pool销毁时,给对象p发送了2个release消息,发送第2个release消息是一个坏访问错误

 

7.快速创建对象的类方法,一般和autorelease结合使用,在MRC里

+ (instancetype)book {

    return [[[self alloc] init] autorelease];

}

在创建对象的类方法中使用autorelease的好处:

  1>节省代码,外面如果想创建一个book,直接调[Book book]就行了,不需要写这么长,[ [ [Book alloc ] init ] autorelease ]

  2>返回对象给别人用的时候,别人不需要去管内存. 例如Book *b = [Book book];别人不需要再release了,因为book方法内部已经做了autorelease

  3>从内存管理原则的角度,因为book方法,不是alloc,也不是retain,所以不需要release

8. 很多系统自带的方法,返回的也是autorelease对象

 
/** 这样创建的字符串 是要release的
NSString *str= [NSString alloc] init];
[str release];
*/
 
系统自带方法 [NSString stringWithFormat:@“这样创建字符串不用release”]; 返回的对象是经过autorelease的,所以不需要release
 
一般来说,除了alloc、new或copy之外的方法创建的对象都被声明了autorelease
比如下面的对象都已经是autorelease的,不需要再release

NSNumber *n = [NSNumber numberWithInt:100];

NSString *s = [NSString stringWithFormat:@"jack"];

NSString *s2 = @"rose";

8.1 这些系统自带方法是怎样产生autorelease对象的?

  1>首先得从构造方法说起,假设有个Book的类,Book有price属性

  - (instancetype)initWithPrice:(float)price{

    if(self == [super init]){

      _price = price;

    }

    return self;

  }

  2>普通类方法

  + (instancetype)book{

    return [[[self alloc]init]autorelease]

  }

  3>类方法+构造

  + (instancetype)bookWithPrice:(float)price{

    return [[[self alloc]initWithPrice:price] autorelease];

  }   

 

iOS autorelease使用详解