奇怪的__block存储变量崩溃

时间:2011-07-28 21:17:49

标签: objective-c

我的代码中存在一个问题,我已将其提炼为以下(愚蠢)示例

NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", nil];

__block NSString *a = @"-1";

[array enumerateObjectsUsingBlock:^(id whoCares, NSUInteger idx, BOOL *stop) {
    a = [NSString stringWithFormat:@"%@ %d", a, idx];
    NSLog(@"%@", a);
}];

NSLog(@"%@", a);

此代码有效,但如果我注释掉第一个NSLog(在块内)代码崩溃了。但是,如果我将格式字符串更改为以下

a = [NSString stringWithFormat:@"%d", idx];

然后代码在没有块内的NSLog的情况下运行良好。

这里发生了什么?我希望我只是误解了一些事情。

1 个答案:

答案 0 :(得分:2)

stringWithFormat:会为您提供一个自动释放的对象,您不会保留该对象。当块退出并且您致电NSLog时,a可能已被解除分配。

一种解决方案可能是使用可变字符串并每次附加到它而不是重新分配。

NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", nil];

NSMutableString *a = [NSMutableString stringWithFormat:@"-1"];

[array enumerateObjectsUsingBlock:^(id whoCares, NSUInteger idx, BOOL *stop) {
    [a appendFormat:@" %d", idx];
}];

NSLog(@"%@", a);