0

複数のView Controllerを持つIOSプロジェクト(ARCが無効)があります。特定のコントローラーの 1 つが MyClass 型のメンバー オブジェクトを初期化しますが、ビュー コントローラーが閉じられると、スレッドを使用して (dispatch-async を使用して) オブジェクトのクリーンアップ メソッドを呼び出して、時間のかかる操作を行います。オブジェクトのメイン キューで [自己解放] を実行することで完了します。これは良い習慣ですか、エラーが発生しますか? 以下は、私が行っていることと同様の例です。

@implementation ViewController

- (void)viewDidLoad
{
    myObj = [[MyClass alloc] init];
}

-(void)viewWillDisappear
{
    [myObj cleanup];
}

@end

//myClass
@implementation MyClass

- (void)cleanup()
{
   dispatch_queue_t myQueue = dispatch_queue_create ("MyClassDeallocQueue", NULL);
   dispatch_async(myQueue, ^{
        //time consuming operations        

        dispatch_async(dispatch_get_main_queue(), ^{
        [self release];
        });
   });

}

@end
4

1 に答える 1

0

これは良い習慣ですか、エラーが発生しますか?

現在、コードの保持/解放のバランスが取れていません。それは間違いなくエラー(オーバーリリース)です。

「それは良い習慣ですか?」-まあ、あなたが何を達成しようとしているのかわかりません。しかし、あなたの目標がブロックが実行されるまで生き続けることである場合、それはキャプチャされるselfという事実だけですでに達成されています。selfしたがって、厳密には areleaseは必要ありません。

ただし、selfメイン スレッドで明示的にリリースしないと、微妙なバグが発生します。ブロックが への最後の参照を持っている可能性がselfあり、任意のスレッドで実行される可能性があるため、selfこの非メイン スレッドでリリースされます。そして、これは禁止されています: UIKit メソッド (dealloc を含む) はメインスレッドで呼び出さなければなりません!

したがって、それは理にかなっているかもしれません:

   [self retain];
   dispatch_async(myQueue, ^{
        // time consuming operation, which captures `self`        
        [self doSomething];
        ...
        // ensure that `dealloc` will be executed on the main thread, if 
        // last reference is held by the block:
        dispatch_async(dispatch_get_main_queue(), ^{
            [self release];
        });
   });

またはそれより短い:

   dispatch_async(myQueue, ^{
        // time consuming operation, which captures `self`        
        [self doSomething];
        ...
        // ensure that `dealloc` will be executed on the main thread, if 
        // last reference is held by the block:
        dispatch_async(dispatch_get_main_queue(), ^{
            [self self];
        });
   });

編集:

「短い」バージョンが実際にトレッドセーフであるか、レースがあるかどうかは興味深い質問です。

がmyQueueでself実行されるブロックで解放されるします。これは、メイン キューで実行されるブロックのキャプチャの効果と同じブロックに保持されるself のキャプチャの効果としてです。次に、問題があります。コメントをお待ちしております。self

于 2014-01-21T15:33:53.343 に答える