1
void f(NSString *s)
{
    [someObj doSomethingWithCompletionHandler:^()
    {
        doSomethingElse(s);
    }];
}

void g()
{
    NSString *s = [[NSString alloc] initWith....];
    f(s);
    [s release];
}

このコードに問題はありますか? sが呼び出される前に破棄される可能性がcompletionHandlerあり、ガベージが に渡されると思いdoSomethingElseます。私は正しいですか?はいの場合、どうすれば修正できますか?

4

1 に答える 1

2

いいえ、大丈夫です。ブロックは保持されますs。を呼び出しsても解放されません[s release]

詳細情報: 保持サイクルを作成すると、問題が発生する可能性があります。ほとんどの場合、次のようになります。

[self doSomeThingWithCompletionHandler:^()
{
   [self beHappy];
}

自己はブロックを保持し、ブロックは自己を保持します。しかし、それほど明白である必要はありません。

NSDictionary *dictionary = @{@"someKey" : someObj, @"someOtherKey", someOtherObj};
//
// lots of stuff happening here
//
[someObj doSomethingWithCompletionHandler:^()
{
   id someOtherObj = dictionary[@"someOtherKey"]
}]

解決策は、weak 変数を宣言することです。

__weak id weakSelf = self;
[self doSomethingWithCompletionHandler:^()
{
    //and to make sure it stays valid if you do multithreaded stuff
    __strong id strongSelf = weakSelf;
   [strongSelf beHappy];
}];

編集:コメントで指摘されているように、元の投稿は非ARCコードを使用していました。この場合、次のものに置き換える必要があり__weakます__unsafe_unretained

于 2013-10-25T14:07:12.103 に答える