如何在回调函数(定义回调时的那个)中使用旧的变量值而不是回调运行时的值?

时间:2012-12-11 13:14:37

标签: objective-c ios callback

让我们看看这个例子:

int a = 1;
[someOperation onCompletion:^(...) {
     NSLog("%d", a);
}];

a = 2;

让我们说someOperation需要1秒才能完成。 所以在控制台上会有“2”。

如何在定义回调时定义带有变量值的回调体(这样在这种情况下回调执行会在控制台上打印“1”)?

在JavaScript中,可以按如下方式完成:

setTimeout("someFunction("+variable+")", 1000);

而不是

setTimeout(function() { someFunction(variable); }, 1000);

但是如何在ObjC中完成这件事呢?

2 个答案:

答案 0 :(得分:1)

如果你尝试

int a = 1;
int64_t delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    NSLog(@"a=%d", a);
});
a = 2;

您会很高兴发现答案是

a=1

因为块的标准行为是捕获它们在创建时引用的变量的值,然后在运行时使用这些存储的值。我确信有一种更明智的说法,但这就是我的工作方式。

答案 1 :(得分:1)

您的假设不正确。 除非使用__block关键字声明它们,否则块会复制局部变量。 所以,在你的情况下:

int a = 1;
[someOperation onCompletion:^(...) {
     NSLog(@"%i", a);
}];

a = 2;

NSLog语句将返回1。 如果你改变它:

int __block a = 1;
[someOperation onCompletion:^(...) {
     NSLog(@"%i", a);
}];

a = 2;

它将返回2,因为在这种情况下,a通过引用

访问