web-dev-qa-db-ja.com

Swiftプログラムでautoreleasepoolを使用する必要がありますか?

このWWDC14プレゼンテーション の17ページに、

Objective-Cでの作業ですか?それでも自動解放プールを管理する必要がある
autoreleasepool {/ *コード* /}

どういう意味ですか?コードベースに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変数は最初の}の後にリリースする必要があります(他の言語と同様)。

86
Ethan

autoreleasepoolパターンは、(= Objective-CコードまたはCocoaクラスを使用して作成されたautoreleaseオブジェクトを返すときにSwiftで使用されます。)Swift関数のautoreleaseパターンObjective-Cの場合と同じように、たとえば、次のSwiftメソッドのレンディション(NSImage/UIImageオブジェクトのインスタンス化))を検討してください。

func useManyImages() {
    let filename = pathForResourceInBundle

    for _ in 0 ..< 5 {
        autoreleasepool {
            for _ in 0 ..< 1000 {
                let image = NSImage(contentsOfFile: filename)
            }
        }
    }
}

これをInstrumentsで実行すると、次のような割り当てグラフが表示されます。

with autoreleasepool

ただし、自動解放プールなしで実行すると、ピークメモリ使用量が高くなることがわかります。

without autoreleasepool

autoreleasepoolを使用すると、Objective-Cでできるように、Swiftで自動解放オブジェクトがいつ割り当て解除されるかを明示的に管理できます。

注:Swiftネイティブオブジェクトを処理する場合、通常、自動解放オブジェクトを受信しません。これが、「Objective-Cで作業する」ときにのみこれを必要とすることに関する警告に言及している理由ですAppleはこの点でより明確でした。しかし、Objective-Cオブジェクト(Cocoaクラスを含む)を扱っている場合、それらは自動リリースオブジェクトである可能性があり、その場合、このSwift Objective-Cのレンディション@autoreleasepoolパターンはまだ便利です。

178
Rob

同等のObjective-Cコードで使用する場合は、Swiftで使用します。

Swift数値変数が最初の後に解放されるべきであることを知るのに十分賢い}

Objective-Cがそうする場合のみ。両方とも、Cocoaのメモリ管理ルールに従って動作します。

もちろん、ARCはnumberがループの反復の終わりに範囲外になることを知っており、ループを保持している場合、そこで解放します。ただし、-[NSNumber numberWithInt:]多かれ少なかれが自動解放されたインスタンスを返したため、オブジェクトが自動解放されたかどうかはわかりません。 -[NSNumber numberWithInt:]のソースにアクセスできないため、知る方法はありません。

4
newacct