Cocoa块变量内存管理

时间:2013-10-25 14:02:45

标签: objective-c cocoa

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

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

此代码中是否存在问题?我猜s可能会在调用completionHandler之前被销毁,垃圾会被传递到doSomethingElse。我对吗?如果是,我该如何解决?

1 个答案:

答案 0 :(得分: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