5

假設我有一個簡單的電話dispatch_async(self.queue, ^{ /* Empty */ }),其中self.queue是一個先前創建的隊列。調度到由對象擁有的隊列是否保留該對象?

是否self獲得由塊在這種情況下保留,因爲沒有self參考塊,但只是作爲dispatch_async()參數?

+1

「自我保留塊」是什麼意思?你的意思是,「自我保留,因爲我將它的隊列傳遞給dispatch_async?」 – Wain

回答

0

不,self將不會被保留,如果該塊既沒有(a)對self的任何明確引用;也不(b)通過引用self的任何實例變量生成的對self的任何隱式引用。調用dispatch_asyncself.queue的存在不會導致它被保留。這是重要的塊內部。

這很容易證明。想象一下,它的實現看起來像一個視圖控制器:

@interface SecondViewController() 
@property (nonatomic, strong) dispatch_queue_t queue; 
@end 

@implementation SecondViewController 

- (void)dealloc 
{ 
    NSLog(@"%s", __FUNCTION__); 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.queue = dispatch_queue_create("com.stackoverflow.17306228", 0); 

    void (^block)(void) = ^(void){ 
     sleep(10); 

     NSLog(@"%s", __FUNCTION__); 
    }; 

    dispatch_async(self.queue, block); 
} 

@end 

如果你把這個視圖控制器的現場,然後立即按「返回」按鈕,彈出它關閉,您將看到的視圖控制器立即被釋放,該塊將繼續執行。但是,如果將類實例變量或屬性添加到block,則會看到視圖控制器保留,直到塊完成。

2

好了,蘋果文檔指出

隊列由系統保留,直到塊已運行到完成 。

所以隊列將被系統保留,直到塊完成執行,但在這種情況下self不會被保留。

感謝@Wain指出我在這個答案的前一個版本中的錯誤。

+1

保留隊列如何保留'self'? – Wain

+0

我可能在這種情況下使用了錯誤的單詞,直到隊列被釋放後才能釋放/分配「self」。如我錯了請糾正我。 – danypata

+1

當然可以。隊列可以繼續存在,而不需要'self'。系統是維護對隊列持續引用的東西。 – Wain

相關問題