感谢this post,我熟悉__block关键字。 它基本上意味着不复制实例,而只是传递其原始引用。
我看到的好处是:
我很好奇,但是,我们应该为这个声明多少烦恼,例如,如果我有这个方法接收callback
块作为参数:
-(void)doSomethingWithCallback:(MyTypeOfCallback)callback;
并且让我们说这个方法使用回调作为参数调用另一个方法。如果我们想在下一个方法中调用它,那么__block
原始callback
参数是否值得:
-(void)doSomethingWithCallback:(MyTypeOfCallback)callback
{
__block MyTypeOfCallback blockCallback = callback;
[self doAnotherThingWithBlock:^(BOOL result) {
if (result)
blockCallback();
}];
}
或者我应该在下一个方法中调用原始的block
参数吗?
-(void)doSomethingWithCallback:(MyTypeOfCallback)callback
{
[self doAnotherThingWithBlock:^(BOOL result) {
if (result)
callback();
}];
}
我问,因为包含__block选项是有意义的,但是我又发现自己在太多的地方做了这件事,而且它开始占用很多代码行。
BTW,这也适用于任何其他类型的参数,而不仅仅是块。
答案 0 :(得分:2)
它基本上告诉编译器不要复制实例
没有。 __block
没有与“实例”有关。 __block
是变量的存储限定符。
__block
意味着变量的相同副本将在原始范围之间共享任何捕获它的任何块(而不是每个块在捕获非变量时获取变量的单独副本) __block
变量)。
在你的情况下,你有一个MyTypeOfCallback
类型的变量,一个(我猜)指针到块的类型。在第一段代码中,您将它设为__block
,因此有一个指针变量,其状态在函数作用域和块(捕获它)之间共享。如果任一范围分配给指针变量,则更改将在另一个范围内可见。
在第二段代码中,你使它成为非__block
,并且当执行块文字时,它会将该指针的值复制到其自己的结构中的单独指针变量中,因此你有两个指针副本。如果您之后分配给函数作用域中的指针变量,则该块的更改将不可见,因为它具有自己的副本。
在这种情况下,两者之间没有区别,因为从未在初始化之后分配给有问题的指针变量。它基本上是一个常量变量,一个副本或两个副本没有区别。
答案 1 :(得分:0)
-(void)doSomethingWithCallback:(MyTypeOfCallback)callback
{
__block MyTypeOfCallback blockCallback = callback;
[self doAnotherThingWithBlock:^(BOOL result) {
if (result)
blockCallback();
}];
}
您可以在块中调用回调
-(void)doSomethingWithCallback:(void(^)(void))callback
{
__block typeof(callback)blockCallback = callback;
[self doAnotherThingWithBlock:^(BOOL result) {
if (result)
blockCallback();
}];
}