2013-01-05 24 views
1

據我所知,ARC中的__block保留該變量。當ARC中的變量是__block和__weak時,這意味着什麼?

__block __weak id observer = [[NSNotificationCenter defaultCenter] addObserverForName:MPMoviePlayerPlaybackDidFinishNotification object:player queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notif){ 
    // reference the observer here. observer also retains this block, 
    // so we'd have a retain cycle unless we either nil out observer here OR 
    // unless we use __weak in addition to __block. But what does the latter mean? 
    }]; 

但是我有麻煩解析這樣的:一個塊內訪問時一個變量的變量已被分配之前,如在本然後可以使用。如果__block導致觀察者被該塊保留,那麼有效的強弱是什麼意思? __weak在這裏做什麼?

+0

''observer'將被初始化,而塊將被複制,因此無論如何您都不能在塊內引用它。 – beefon

+2

'__weak' +'__block'表示該變量是弱引用的,可以通過在該塊中執行的代碼進行更改。 – beefon

+0

第一條評論並不完全正確,如果您知道在分配完成之前該塊不會執行,您可以參考它。 (另見8477629) – Aaron

回答

6

__block意味着該變量與全局一樣,可以在當前幀堆棧中存活,並且可以在範圍內聲明的塊訪問。

__weak表示該變量不保留指向的對象,但如果該對象被釋放,則指針將被設置爲零。

在你的情況下,觀察者捕獲addObserverForName:object:queue:usingBlock:的返回值,所以它不需要很強。如果能力強大,那麼它將保留觀察員,使其成爲全球性的,直到強有力的參照被設定爲零。

​​

這個例子打印(空),讓我們來看看發生了什麼:

  • 字符串@ 「喂」 有1個爲ARC引用計數;
  • 它在塊中使用,但由於它很弱,它不被塊保留,所以它仍然有計數到1;
  • 該塊被返回並執行,因爲我們退出foo函數作用域,字符串被釋放並且指針x被設置爲nil。

所以,你可以只是做這樣的:

void (^foo())() 
{ 
    NSString* str= [[NSString alloc]initWithFormat: @"Hey"]; 
    return^
    { 
     NSLog(@"%@",str); 
    }; 
} 

有沒有問題:str是強大的默認所以它的俘虜,你不需要__block符。

+0

但是根據http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html:「在ARC模式下,__block id x;默認爲保留x(就像所有其他值)「 – Aaron

+0

我想這只是意味着它像往常一樣被堆棧幀保留,而不是它被塊保留? – Aaron

+0

它默認保留x,但使用__weak說明符則不會。 「 –