В дни ручного управления памятью MRC (до ARC для Obj-C) для управления потоком памяти в приложении iOS приходилось использовать функции keep() и release(). В эпоху Obj-C в iOS использование autoreleasepool было важным для предотвращения утечек памяти вашего приложения в определенных случаях
Поскольку управление памятью iOS работает на основе счетчика сохраненных объектов, пользователи могут использовать эти методы, чтобы сигнализировать, сколько раз на объект ссылаются, чтобы его можно было безопасно отключить, если это значение когда-либо достигнет нуля.
Autorelease()
- механизм отложенного удаления объекта в ARC. Является экземпляром NSAutoreleasePool
❗ Вместо того, чтобы мгновенно уменьшить счетчик удержания объекта, autorelease()
добавляет объект в пул объектов, которые необходимо освободить когда-нибудь в будущем, но не сейчас. По умолчанию пул освобождает эти объекты в конце RunLoop'a выполняемого потока, чего более чем достаточно, чтобы покрыть все случаи. Или почти все
Однако autorelease()
работает только для объектов Objective-C (NSObject), которые получили сообщение об автоматическом освобождении . Для объектов, которые исходят от Swift, это все равно не работает.
Ответ в зависимости от обстоятельст:
-
Если наш проект содержит obj-c код, то да. В чистом swift проекте возможно это потребуется только в библиотеках, которые содержат obj-c код.
-
autoreleasepool нужен чтобы не переполнялся стек. Рекурсия может вызваться миллиард раз, произойдет переполнение стека. Авторелиз решает вопрос.
-
Для оптимизации памяти. Н/р: при переборе в цикле загружаемых картинок
// some function body
for _ in 0..<10 {
autoreleasepool {
// UIImage inherits NSObject (Objective-C)
let image = UIImage(contentsOfFile: "image.jpg") // heavy
}
}
Представим, что каждое изображение занимает в памяти ~20Мб. Таким образом, без autoreleasepool к концу функции будет занимать ~200Mb. Но теперь на весь вызов функции уходит около 20 МБ. Таким образом, никаких существенных скачков памяти там нет.
У каждой функции есть свой pool. Когда функция вызывается она создает свой пул, который помещается на вершину стека. Каждый объект, созданный внутри функции и получивший сообщение об автоосвобождении, добавляется в пул. Когда функция завершается, пул освобождается.
Однако если внутри функции вручную создать другой пул (@autoreleasepool
), объекты будут добавлены именно туда, поскольку теперь этот пул помещен на вершину стека. Таким образом, объекты добавляются в последний созданный пул и удаляются, когда его область видимости завершилась.
В общем, нет необходимости создавать пулы вручную. Например, UIKit и AppKit автоматически создают пул при запуске события касания и освобождают его, когда событие заканчивается (итерация цикла выполнения).
3.1.3.1.2 MRC Theme | Back To iOSWiki Contents | 3.1.3.1.4 Capture List Theme Folder