Нужно ли использовать 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:].