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 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 回答