Нужно ли использовать autoreleasepool в программе Swift?
На странице 17 это презентация WWDC14, говорится
Работа с Objective-C? Все еще нужно управлять пулами авторекламы
autoreleasepool {/* code */}
Что это значит? Означает ли это, что если в моей базе кода нет файлов Objective-C, autoreleasepool {}
не требуется?
В ответе на связанный вопрос, есть пример, где autoreleasepool
может быть полезным:
- (void)useALoadOfNumbers {
for (int j = 0; j < 10000; ++j) {
@autoreleasepool {
for (int i = 0; i < 10000; ++i) {
NSNumber *number = [NSNumber numberWithInt:(i+j)];
NSLog(@"number = %p", number);
}
}
}
}
Если приведенный выше код переводится в Swift с отбрасыванием autoreleasepool
, будет ли Swift достаточно умным, чтобы знать, что переменная number
должна быть выпущена после первого }
(как это делают некоторые другие языки)?
Ответы
Ответ 1
Шаблон autoreleasepool
используется в Swift при возврате объектов autorelease
(созданных вашим кодом Objective-C или с использованием классов Cocoa). Образец autorelease
в Swift работает так же, как в Objective-C. Например, рассмотрим это быстрое преобразование вашего метода (создание экземпляров объектов NSImage
/UIImage
):
func useManyImages() {
let filename = pathForResourceInBundle
for _ in 0 ..< 5 {
autoreleasepool {
for _ in 0 ..< 1000 {
let image = NSImage(contentsOfFile: filename)
}
}
}
}
Если вы запустите это в Инструментах, вы увидите график распределений, как показано ниже:
![with autoreleasepool]()
Но если вы сделаете это без пула автозапуска, вы увидите, что пиковое использование памяти выше:
![without autoreleasepool]()
autoreleasepool
позволяет вам явно управлять тем, когда объекты автоопределения освобождаются в Swift, так же, как вы были в Objective-C.
Примечание. При работе с родными объектами Swift вы обычно не будете получать объекты автозапуска. Вот почему в презентации упоминалось об этом только о необходимости "работать с Objective-C", хотя я бы хотел, чтобы Apple была более ясна в этом вопросе. Но если вы имеете дело с объектами Objective-C (включая классы Cocoa), они могут быть объектами автоопределения, и в этом случае это быстрое преобразование шаблона Objective-C @autoreleasepool
по-прежнему полезно.
Ответ 2
Если вы будете использовать его в эквивалентном Objective-C коде, то вы будете использовать его в Swift.
будет Swift достаточно умным, чтобы знать, что числовая переменная должна быть выпущенный после первого}
Только если Objective-C. Оба работают по правилам управления памятью Cocoa.
Конечно, ARC знает, что number
выходит за пределы области действия в конце этой итерации цикла, и если она сохранит ее, она освободит ее там. Однако это не говорит вам, был ли объект автореализован, потому что -[NSNumber numberWithInt:]
может возвращать или не возвращать экземпляр с автореализацией. Вы не можете узнать, потому что у вас нет доступа к источнику -[NSNumber numberWithInt:]
.