5

クラス(非ARC環境)があるとします:

@interface SomeObject : NSObject {
    UILabel *someLabel;
    dispatch_queue_t queue;
}
- (void)doAsyncStuff;
- (void)doAnimation;
@end

@implementation SomeObject

- (id)init {
    self = [super init];
    if (self) {
        someLabel = [[UILabel alloc] init];
        someLabel.text = @"Just inited";
        queue = dispatch_queue_create("com.me.myqueue", DISPATCH_QUEUE_SERIAL);
    }
    return self;
}

- (void)doAsyncStuff {
    dispatch_async(queue, ^{
        ...
        // Do some stuff on the current thread, might take a while
        ...
        dispatch_async(dispatch_get_main_queue(), ^{
            someLabel.text = [text stringByAppendingString:@" in block"];
            [self doAnimation];
        }
    }
}

- (void)doAnimation {
    ...
    // Does some animation in the UI
    ...
}

- (void)dealloc {
    if (queue) {
        dispatch_release(queue);
    }
    [someLabel release];
    [super dealloc];
}

私のブロックが開始され、このオブジェクトのインスタンスへの参照を保持している他のすべてがそれを解放した場合、ネストされたブロックがインスタンス変数 (および自己) を参照するため、dealloc が呼び出されないことが保証されますか? その deallocネストされたブロックが終了した後に発生しますか? 私の理解では、私のブロックには自己への強い参照があるため、これはコーシャでなければなりません.

4

2 に答える 2

3

あなたが述べた理由から、これは問題ありません。

注意すべき重要なことは、クラス ( で表されるself) が何らかの方法でブロックを保持する場合、保持サイクルを作成することです。インラインで定義して に渡すのでdispatch_async、問題ありません。

于 2013-02-07T18:14:48.960 に答える
0

あなたは、絶対に正しい。ブロックは2つの場合に自己を保持します:

  1. あなたはブロックの中で自分自身を使います。
  2. ブロック内で直接インスタンス変数にアクセスします。

ネストされたブロックは、両方の点でうまくいきます。したがって、ブロックの実行が終了した後に、deallocが発生します。

注意すべきもう1つの興味深い点は、yourqueueもインスタンス変数であるということです。私の最初の考えは、これはインスタンス変数であるためself、ブロックの実行が完了するまで保持されるというものでした。ただし、テストしたときに実際に発生するのは、queue保持されselfて割り当てが解除されるだけです。しかし、これに関するドキュメントを見つけることができません。

于 2013-02-07T20:34:12.950 に答える