Блоки пула авторезистов 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 в течение нескольких секунд, чтобы понять механизм управления памятью.
Ответы
Ответ 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 откладывают выпуск объекта до конца пула, что позволяет избежать его освобождения до того, как он достигнет конца. Таким образом, в основном, убедитесь, что объект не будет выпущен до конца пула.