16

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

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's lifespan ends, right? 
    // so why do we need to call autorelease then?! 
    } 

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

ответ

27

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 

} 
+0

так как это отвечает на мой вопрос? Я представил простой пример, чтобы избежать подобных ответов, которые не имеют большого отношения к вопросу.Я также добавил комментарии к небольшому примеру. – Teo

+1

Как правило, вы используете только пулы автозапуска в функции, где есть большое использование памяти, и вам нужно освободить ее раньше, чем обычно. Этот пункт призван добавить контекст. – Kibitz503

+0

Итак, в случае без ARC env, '' MyObject * obj = [[MyObject alloc] init]; '' внутри пула автозапуска будет утечкой памяти, но в ARC env компилятор автоматически добавит запрос на выпуск для объект или почему он больше не является утечкой памяти? – Teo

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

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

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

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

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

+0

Хорошее разъяснение об утечке. Это утечка с или без пула авторефератов, обернутых вокруг него! – Kibitz503

+0

Означает ли это, что если я использую ARC и выпущу объект из-за границы '' @autoreleasepool {} '', объект все еще существует до конца блока @autoreleasepool? – confile

+0

Это зависит от кода. В конце блока autoreleasepool отправляются все незавершенные автореализаторы, созданные в этом блоке. Я не знаю, что означает «выпустить объект» в вашем примере. Вероятно, вы захотите составить конкретный пример кода и задать новый вопрос. –

0

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