Блоки пула авторезистов iOS - программирование
Подтвердить что ты не робот

Блоки пула авторезистов iOS

Я читал документацию из apple об управлении памятью, когда я добрался до блоков пула автозапуска, и что-то заставило меня задуматься.

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

Я не уверен, что полностью понимаю это. Любой объект, созданный внутри блока пула автозаполнения, все равно будет выпущен в конце блока, потому что это срок службы. Зачем вам нужно вызывать авторекламу для объекта, когда он будет выпущен, когда он достигнет конца блока?

Чтобы быть более ясным, я приведу пример, о чем я думаю:

   @autoreleasepool {

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

    /* use the object*/
   //....
   // in the end it should get deallocated because it lifespan ends, right?
   // so why do we need to call autorelease then?!
  }

PS: Пожалуйста, не говорите мне, что из-за ARC нам не нужно что-то делать, потому что ARC заботится о них. Я полностью это понимаю, но я хочу оставить ARC в течение нескольких секунд, чтобы понять механизм управления памятью.

4b9b3361

Ответ 1

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 

}

Ответ 2

(В основном просто добавив дополнительный фон, @Kibitz503 дает вам правильный ответ.)

@autoreleasepool {

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

  /* use the object*/
  //....
  // in the end it should get deallocated because it lifespan ends, right?
  // so why do we need to call autorelease then?!
}

PS: Пожалуйста, не говорите мне, что из-за ARC нам не нужно что-то делать, потому что ARC заботится о них. Я полностью это понимаю, но я хочу оставить ARC в течение нескольких секунд, чтобы понять механизм управления памятью.

ОК, не рассматривайте ARC. В вышесказанном, без ARC, obj не будет освобожден. Только потому, что ARC добавляет дополнительные вызовы release, возможно, будет освобожден (учитывая ваш пример, мы на самом деле понятия не имеем, поскольку мы не знаем, что происходит в use the object).

Как объясняет @Kibitz503, "релиз" не означает "освобождение". В конце блока пул авторасчетов сливается, что означает, что любые ожидающие autorelease вызовы отправляются как release в конце блока. Если это приведет к тому, что объект достигнет значения удержания 0, он будет освобожден.

Но независимо от того, находится ли это в блоке или нет, без ARC это утечка.

Ответ 3

Пулы Autorelease откладывают выпуск объекта до конца пула, что позволяет избежать его освобождения до того, как он достигнет конца. Таким образом, в основном, убедитесь, что объект не будет выпущен до конца пула.