__block表示Objective C中的方法参数?

时间:2015-08-08 19:32:31

标签: objective-c automatic-ref-counting objective-c-blocks

感谢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,这也适用于任何其他类型的参数,而不仅仅是块。

2 个答案:

答案 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();
    }];
}