1. ホーム
  2. memory-management

[解決済み] Swiftのプログラムでautoreleasepoolを使用する必要はありますか?

2022-11-07 03:45:37

質問

の17ページで このWWDC14のプレゼンテーション には、次のように書かれています。

<ブロッククオート

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 変数が最初の } (の後に解放されるべきでしょうか?)

どのように解決するのですか?

この autoreleasepool を返すとき、Swift ではこのパターンが使われます。 autorelease オブジェクト (Objective-C コードまたは Cocoa クラスを使用して作成されたもの) を返すときに使用されます。そのため 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で実行すると、アロケーショングラフに 5 のような小さな丘があります(外側の for ループのため)。

しかし、自動解放プールを使用せずに実行すると、ピーク時のメモリ使用量が多くなることがわかります。

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

注意: Swift ネイティブオブジェクトを扱うとき、一般的に autorelease オブジェクトを受け取ることはありません。これが、プレゼンテーションで、"Objective-C" で作業するときだけこれが必要だという注意事項を述べた理由ですが、私は Apple がこの点についてもっと明確であればと思いました。しかし、あなたが Objective-C オブジェクト (Cocoa クラスを含む) を扱っている場合、それらは autorelease オブジェクトである可能性があり、その場合、この Objective-C の Swift レンダリングの @autoreleasepool パターンはまだ有用です。