0

Question: Am I using this block correctly? No leaks or retain cycles?

Question 1.5: Is this good style or should I just do an inline block?

typedef void(^completionBlock)(void);

...

-(completionBlock)completionBlock{
    return ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:kFetchNewTopicsAndReloadTableData object:nil];
    };
}

..

-(void)refresh
{
    [self dismissViewControllerAnimated:YES completion:[self completionBlock]];
}
4

1 に答える 1

1

selfブロックは、インスタンス変数を参照することによって、明示的または暗黙的に を参照しません。したがって、保持されませんself。一応保持するのはメタクラスNSNotificationCenterだけであり、私が仮定するのはグローバル定数でありkFetchNewTopicsAndReloadTableData、どちらの行為も保持されません。

したがって、そのブロックは一時的なオブジェクトをまったく処理しないため、保持サイクルは絶対にありません。

残っていてもself問題ありません。次のようなものと比較対照します。

@implementation SomeClass
{
    block_t someHandler;
}

...
    someHandler = [^{ [self doSomething]; } copy];

selfこれにより、ブロックが保持され、ブロックによって保持されるため、保持サイクルが作成selfされます。後でサイクルを壊す可能性がありますが、弱い参照を使用するだけで、最初からサイクルを作成しない方がはるかに安全です。

あなたのようにブロックを返すのが悪い形であるかどうかについて: 技術的には、ブロックをcopy返すために d する必要があるという理由で、はい. ブロックが宣言されている範囲を超えて使用する場合は、ブロックをコピーする必要があります。インラインの場合、コピーする必要はありません。これはdismissViewControllerAnimated:.... そのブロックは、グローバル状態以外は何もキャプチャしないため、それを回避できますが、それはコピーが本質的に無料であることも意味するため、例外を作成する価値はありません.

あなたが求めている可能性が高いものについては、ブロックの宣言をラップする追加のメソッドを追加するために構文が複雑になりすぎていることは間違いありませんが、同じブロックが複数回必要な場合は、因数分解の通常のルールが適用されます。

于 2013-10-31T02:44:14.950 に答える