1. ホーム
  2. objective-c

[解決済み】ARCで@autoreleasepoolがまだ必要なのはなぜですか?

2022-04-12 04:11:57

質問

ARC(自動参照カウント)を使えば、Objective-Cのオブジェクトでは、ほとんどの場合、メモリ管理について考える必要はありません。また NSAutoreleasePool はもう存在しませんが、新しい構文があります。

@autoreleasepool {
    …
}

私の疑問は、手動でリリース/オートリリースを行う予定がないのに、なぜこれが必要なのか、ということです。


EDITです。 全ての回答やコメントから私が得たものを簡潔にまとめると。

新しい構文。

@autoreleasepool { … } は新しい構文で

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
…
[pool drain];

もっと重要なのは

  • ARCは autorelease と同様に release .
  • そのためには、自動解放プールが必要です。
  • ARCは自動解放プールを作成してくれません。 しかし
    • すべてのCocoaアプリのメインスレッドには、すでにオートリリース・プールが入っています。
  • を使用したい場合が2つあります。 @autoreleasepool :
    1. セカンダリスレッドで、オートリリースプールがない場合、リークを防ぐために、以下のような自作が必要です。 myRunLoop(…) { @autoreleasepool { … } return success; } .
    2. よりローカルなプールを作りたい場合、@mattjgalloway さんの回答で紹介されています。

解決方法は?

ARCは、リテイン、リリース、オートリリースを取り除くのではなく、必要なものを追加してくれるのです。そのため、retainの呼び出し、releaseの呼び出し、autoreleaseの呼び出し、autoreleaseのプールはまだ存在します。

新しいClang 3.0コンパイラとARCで行われた他の変更の1つに NSAutoReleasePool@autoreleasepool コンパイラディレクティブを使用します。 NSAutoReleasePool は常に少し特殊な "オブジェクト" で、それを使用する構文がオブジェクトと混同されないようにし、一般的にもう少しシンプルになるようにしたのです。

つまり、基本的には @autoreleasepool というのも、まだオートリリースプールの心配をしなければならないからです。というのも、自動解放プールが存在するからです。 autorelease の呼び出しがあります。

オートリリースプールの使用例です。

- (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);
            }
        }
    }
}

確かに、非常に不自然な例ではありますが、もしあなたが @autoreleasepool の内側で、外側の for -ループを通過するたびに 10000 個のオブジェクトを解放するのではなく、1000000 個のオブジェクトを後で解放することになります。 for -ループになります。

更新しました。 この回答も参照してください -。 https://stackoverflow.com/a/7950636/1068248 - なぜかというと @autoreleasepool はARCとは関係ない。

更新しました。 ここで起こっていることの内部を覗いてみたところ ブログで紹介しています。 . このページをご覧になれば、ARCが何をしているのか、そして新しいスタイルがどのようなものかがおわかりいただけると思います。 @autoreleasepool とスコープを導入することで、コンパイラがどのようなリテイン、リリース & autoreleases が必要かという情報を推論するために使用されます。