На странице 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
drop, будет ли Swift достаточно умен, чтобы знать, что number
переменная должна быть выпущена после первой }
(как это делают некоторые другие языки)?
autoreleasepool
в Swift нет документации . Я расширил ваш вопрос и задал его на форумах разработчиков .Ответы:
autoreleasepool
Шаблон используется в Swift при возвращенииautorelease
объектов (созданных либо кодом Objective-C или с помощью классов какао).autorelease
Шаблон в функции Swift много , как это делает в Objective-C. Например, рассмотрим эту Swift-версию вашего метода (создание экземпляровNSImage
/UIImage
объектов):func useManyImages() { let filename = pathForResourceInBundle for _ in 0 ..< 5 { autoreleasepool { for _ in 0 ..< 1000 { let image = NSImage(contentsOfFile: filename) } } } }
Если вы запустите это в инструментах, вы увидите график распределения, подобный следующему:
Но если вы сделаете это без пула автозапуска, вы увидите, что пиковое использование памяти выше:
autoreleasepool
Позволяет явно управлять , когда autorelease объекты высвобождены в Swift, так же , как вы были в состоянии в Objective-C.Примечание. При работе с собственными объектами Swift вы обычно не получаете объекты с автоматическим выпуском. Вот почему в презентации упоминалось предостережение о необходимости этого только при «работе с Objective-C», хотя я бы хотел, чтобы Apple была более ясной по этому поводу. Но если вы имеете дело с объектами Objective-C (включая классы Какао), они могут быть объектами с автоматическим выпуском, и в этом случае это представление Swift
@autoreleasepool
шаблона Objective-C по-прежнему полезно.источник
println
по прибытииdeinit
, и это становится довольно легко проверить точно , когда объекты освобождаться. Или наблюдайте в инструментах. Отвечая на ваш вопрос, похоже, что объекты Swift возвращаются из функций с +1 счетчиком сохранения (не для объектов с автоматическим выпуском), и вызывающая сторона будет легко управлять владением с этой точки (например, если и когда возвращенный объект выпадает из области видимости, он немедленно освобождается, а не помещается в пул автозапуска).NSImage
/UIImage
objects и более последовательно проявил проблему (и, честно говоря, это более частый пример проблемы, поскольку пиковое использование памяти часто проблематично только при работе с более крупными объектами; практическим примером этого может быть рутинное изменение размера кучи изображений). Я также воспроизвел поведение, вызывающее код Objective-C, который явно создает объекты автозапуска. Не поймите меня неправильно: я думаю, что пулы с автоматическим выпуском в Swift нужны реже, чем в Objective-C, но это все еще играет роль.pathForResource:ofType:
раз.pathForResource:ofType:
пример больше не работает в Xcode 6.3 / Swift 1.2. :)Если бы вы использовали его в эквивалентном коде Objective-C, вы бы использовали его в Swift.
Только если Objective-C это сделает. Оба работают согласно правилам управления памятью Какао.
Конечно, ARC знает, что
number
выходит за рамки в конце этой итерации цикла, и, если он сохранил это, он освободит его там. Однако это не говорит вам, был ли объект выпущен автоматически, потому что-[NSNumber numberWithInt:]
мог или не мог вернуть автоматически выпущенный экземпляр. Вы не можете узнать это, потому что у вас нет доступа к источнику-[NSNumber numberWithInt:]
.источник
autoreleasepool
конструкция совершенно не нужна. Но если ваш код Swift обрабатывает объекты Objective-C (включая объекты Какао), они действительно следуют шаблонам автозапуска, и, таким образом,autoreleasepool
конструкция становится полезной.