2015-08-08 82 views
1

非常感谢this post,我熟悉__block关键字。 它基本上意味着不复制实例,而只是传递它的原始参考。我认为这样做是目标C中的方法参数__block?

好处:

  • 该实例所作的块内的任何修改都会反映原始实例。
  • 避免复制我们要在块中使用的实例的“浪费”。

我很好奇,不过,有多少我们应该真正与这个声明麻烦,例如,如果我有这个方法接收一个callback块作为参数:

-(void)doSomethingWithCallback:(MyTypeOfCallback)callback;

,让我们说这个方法调用另一个回调作为参数的方法。它是那么值得__blockcallback参数,如果我们想要把它下一个方法里面:

-(void)doSomethingWithCallback:(MyTypeOfCallback)callback 
{ 
    __block MyTypeOfCallback blockCallback = callback; 
    [self doAnotherThingWithBlock:^(BOOL result) { 
     if (result) 
      blockCallback(); 
    }]; 
} 

,或者我应该简单地调用next方法里面原来block参数?

-(void)doSomethingWithCallback:(MyTypeOfCallback)callback 
{ 
    [self doAnotherThingWithBlock:^(BOOL result) { 
     if (result) 
      callback(); 
    }]; 
} 

我这么问是因为它是有道理的包括__block选择,但后来我又发现自己做了太多的地方,它开始采取许多行代码。

顺便说一句,这也适用于任何其他类型的参数,不仅块。

+9

没有任何理由可言在你的例子使用'__block'。 '__block'的使用是当一个块外声明的变量需要在块内部修改时。你没有试图重新赋值'callback',所以'__block'变量'blockCallback'没有用处。 – rmaddy

+0

好的,那么避免复制该实例呢? – mllm

+3

这不是你应该担心的。让编译器做它的事情。开发人员不成熟的优化会导致比以往更多的问题。 – rmaddy

回答

1

它基本上是告诉编译器不能复制

__block号有什么做“实例”的实例。 __block变量的存储限定符。

__block上的变量意味着变量的相同副本将在原始范围之间共享任何捕获它的任何块(而不是每个块在捕获非变量时获取变量的单独副本) 。

在你的情况,你有一个MyTypeOfCallback类型的变量,(我猜)指针到块的类型。在第一段代码中,您将它设为__block,所以有一个指针变量,其状态在函数作用域和块(它捕获它)之间共享。如果任何一个作用域分配给指针变量,则该更改将在另一个作用域中可见。

在第二段代码中,您将它设为非__block,并且当块文字被执行时,它将该指针的值在那一刻复制到它自己的结构中的单独指针变量中,以便您指针的两个副本。如果事后分配给函数作用域中的指针变量,则更改对块不可见,因为它有自己的副本。

在这种情况下,两者之间没有区别,因为在初始化后从未分配给所讨论的指针变量。它基本上是一个常数变量,一个副本或两个副本没有区别。

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