0

让我们看看这个例子:

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 中完成这件事呢?

4

2 回答 2

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

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

于 2012-12-11T13:20:36.383 回答
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 是通过引用访问的

于 2012-12-11T13:27:57.980 回答