Как работает autorelease и почему он откладывает освобождение памяти?

«Как работает autorelease и почему он откладывает освобождение памяти?» — вопрос из категории Управление памятью, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

autorelease откладывает отправку сообщения release объекту до завершения текущего autorelease pool, обычно в конце run loop цикла.

Механизм работы:

  1. Объект помещается в текущий autorelease pool
  2. При вызове drain() (или автоматически в конце run loop) pool отправляет release всем объектам
  3. Если счетчик ссылок достигает нуля, вызывается dealloc

Зачем это нужно:

  • Возврат объектов из методов — позволяет безопасно вернуть вновь созданный объект без немедленного освобождения
  • Удобство — избавляет от необходимости точно отслеживать моменты release в ручном управлении памятью

Пример (ручное управление памятью):

// Без autorelease — объект освободится ДО возврата из функции
- (NSString *)badMethod {
    NSString *temp = [[NSString alloc] initWithString:@"test"];
    [temp release]; // Освобождаем сразу
    return temp;    // ОШИБКА: возвращаем освобожденный объект!
}

// С autorelease — объект будет освобожден позже
- (NSString *)goodMethod {
    NSString *temp = [[[NSString alloc] initWithString:@"test"] autorelease];
    return temp; // Безопасно, объект будет жить до конца run loop
}

В ARC-среде:

  • Явное использование autorelease почти не требуется
  • Компилятор автоматически вставляет оптимизированные вызовы
  • Autorelease pools создаются автоматически для каждого run loop
  • Можно создавать вложенные pools для контроля времени жизни:
    autoreleasepool {
    // Создание множества временных объектов
    for _ in 0..<10000 {
        _ = UIImage(contentsOfFile: path)
    }
    // Все autoreleased объекты освобождаются здесь
    }

Проблема: Большое количество autoreleased объектов может вызвать всплеск использования памяти.