Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS autorelease pool blocks

I was reading the documentation from apple about memory management when I got to autorelease pool blocks and something got me thinking.

 Any object sent an autorelease message inside the autorelease pool block is  
 released at the end of the block.

I am not sure I fully understand this. Any object created inside an autorelease pool block gets released at the end of the block anyway because that is it's life span. Why would you need to call autorelease to the object when it is going to get released anyway when it reaches the end of the block?

To be clearer, I will give an example, of what I am thinking:

   @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?!
  }

PS: Please don't tell me that because of ARC we don't need to do some things because ARC takes care of them. I am fully aware of that, but I want to leave ARC aside for just a few moments to understand the mechanism of memory management.

like image 342
Teo Avatar asked Apr 24 '13 17:04

Teo


People also ask

What is Autorelease pool IOS?

An autorelease pool stores objects that are sent a release message when the pool itself is drained. Important. If you use Automatic Reference Counting (ARC), you cannot use autorelease pools directly. Instead, you use @autoreleasepool blocks.

What is an Autorelease object?

An autorelease pool is actually a collection of objects that will be released at some point in the future (either at the end of the thread's run loop or at the end of the scope of an autorelease pool). When a pool is drained, all the objects in the pool at that time are sent the release message.

What is retain in IOS?

You send an object a retain message when you want to prevent it from being deallocated until you have finished using it. An object is deallocated automatically when its reference count reaches 0 . retain messages increment the reference count, and release messages decrement it.


2 Answers

Autorelease just removes a retain count from the object it does not "free" the memory immediately like in c. When the autorelease pool ends all auto released objects with a count of 0 will have their memory freed up.

Sometimes you create a lot of objects. An example would be a loop that is creating new strings every time it iterates and adds new data to the string. You may not need the previous versions of the string and will want to free up memory used by those. You can accomplish this by explicitly using the autorelease pool instead of waiting for it to be done naturally.

//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 

}
like image 84
Kibitz503 Avatar answered Oct 14 '22 15:10

Kibitz503


(Mostly just giving some additional background; @Kibitz503 is getting you to the right answer.)

@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?!
}

PS: Please don't tell me that because of ARC we don't need to do some things because ARC takes care of them. I am fully aware of that, but I want to leave ARC aside for just a few moments to understand the mechanism of memory management.

OK, let's not consider ARC. In the above, without ARC, obj would not be deallocated. Only because ARC adds additional release calls does possibly get deallocated (given your example, we actually have no idea since we don't know what happens in use the object).

As @Kibitz503 explains, "release" does not mean "deallocate." At the end of the block, the autorelease pool drains, which means any pending autorelease calls are sent as release at the end of the block. If that leads to the object reaching a 0 retain count, then it is deallocated.

But whether the above is in a block or not, without ARC it is a leak.

like image 40
Rob Napier Avatar answered Oct 14 '22 15:10

Rob Napier