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