iOS自动释放池块

Teo*_*Teo 17 memory-management autorelease nsautoreleasepool ios objective-c-blocks

我正在阅读苹果关于内存管理的文档,当我开始自动发布池块时,有些东西让我思考.

 Any object sent an autorelease message inside the autorelease pool block is  
 released at the end of the block.
Run Code Online (Sandbox Code Playgroud)

我不确定我是否完全理解这一点.在自动释放池块中创建的任何对象无论如何都会在块的末尾释放,因为这是它的生命周期.为什么当它到达块的末尾时无论如何都要释放它时,你需要调用autorelease?

为了更清楚,我将举例说明我的想法:

   @autoreleasepool {

    MyObject *obj = [[MyObject alloc] init]; // no autorelease call here

    /* use the object*/
   //....
   // in the end it should get deallocated because it's lifespan ends, right?
   // so why do we need to call autorelease then?!
  }
Run Code Online (Sandbox Code Playgroud)

PS:请不要告诉我,因为ARC我们不需要做一些事情,因为ARC会照顾它们.我完全清楚这一点,但我想暂时将ARC放在一边,以了解内存管理的机制.

Kib*_*503 29

Autorelease只是从对象中删除一个保留计数,它不像c中那样立即"释放"内存.当自动释放池结束时,所有自动释放的对象计数为0将释放其内存.

有时你会创建很多对象.一个例子是每次迭代时创建新字符串并将新数据添加到字符串的循环.您可能不需要以前版本的字符串,并且想要释放那些使用的内存.您可以通过显式使用自动释放池来完成此操作,而不是等待它自然地完成.

//Note: answers are psudocode

//Non Arc Env
@autoreleasepool 
{

    MyObject *obj = [[MyObject alloc] init]; // no autorelease call here
    //Since MyObject is never released its a leak even when the pool exits

}
//Non Arc Env
@autoreleasepool 
{

    MyObject *obj = [[[MyObject alloc] init] autorelease]; 
    //Memory is freed once the block ends

}
// Arc Env
@autoreleasepool 
{

    MyObject *obj = [[MyObject alloc] init]; 
    //No need to do anything once the obj variable is out of scope there are no strong pointers so the memory will free

}

// Arc Env
MyObject *obj //strong pointer from elsewhere in scope
@autoreleasepool 
{

    obj = [[MyObject alloc] init]; 
    //Not freed still has a strong pointer 

}
Run Code Online (Sandbox Code Playgroud)

  • "自动释放只是从对象中移除一个保留计数,它不会像c中那样立即"释放"内存." 不,`autorelease`只是将一个对象添加到自动释放池中."当自动释放池结束时,所有自动释放的对象计数为0将释放其内存." 不,当自动释放池结束时,它会释放池中的所有对象.任何地方的`release`(无论是通过autorelease池还是其他地方)都可能导致对象被释放,如果`release`之前的保留计数为1. (3认同)

Rob*_*ier 6

(主要是提供一些额外的背景; @ Kibitz503可以帮助您找到正确的答案.)

@autoreleasepool {

  MyObject *obj = [[MyObject alloc] init]; // no autorelease call here

  /* use the object*/
  //....
  // in the end it should get deallocated because it's lifespan ends, right?
  // so why do we need to call autorelease then?!
}
Run Code Online (Sandbox Code Playgroud)

PS:请不要告诉我,因为ARC我们不需要做一些事情,因为ARC会照顾它们.我完全清楚这一点,但我想暂时将ARC放在一边,以了解内存管理的机制.

好的,我们不要考虑ARC.在上面,没有ARC,obj就不会被解除分配.只因为ARC增加额外的release调用可能会被释放(假设你的例子,我们实际上不知道,因为我们不知道发生了什么use the object).

正如@ Kibitz503所解释的那样,"发布"并不意味着"解除分配".在块结束时,自动释放池耗尽,这意味着在块结束时autorelease发送任何挂起的呼叫release.如果这导致对象达到0保留计数,则将其解除分配.

但无论上述情况是否存在,如果没有ARC,这都是一次泄密.