2017-02-19 25 views
0

說地圖是一個NSDictioanry,我的理解是因爲res的地址在塊中沒有改變,所以我們不需要使用__block。它是否正確?是否有必要使用__block類型說明符來更改塊中的可變對象?

//__block NSMutableArray *res = [@[] mutableCopy]; 
NSMutableArray *res = [@[] mutableCopy]; 
__block NSInteger i = 0; 
[map enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSArray *v, BOOL *stop) { 
    [res addObject:v]; 
    i++; 
}]; 

順便說一句,我已經運行的代碼,它工作正常。

+0

編譯器是否抱怨?運行代碼並打印'res'。怎麼了? – vadian

+0

我已經運行它工作正常 – user3315620

+0

然後答案是:否:-)編譯器會告訴你是否缺少__block。 – vadian

回答

2

__block類型說明符僅用於存儲通常會出現在堆棧上的可變項目。由於塊不能保證只在創建它的方法範圍內調用(這稱爲轉義),所以它可能需要在它們消失後引用的變量進行變異。對堆棧中的東西(如你的例子中的i)的引用可以成爲懸掛指針,如果塊被拖到原始方法或函數的末尾,所以如果它們要被突變,它們需要被存儲在其他地方比堆棧。 __block說明符告訴編譯器將該變量放在單獨的存儲器中,每當調用塊時該變量都將有效。

對於堆分配的東西(如上面的res),這不是必需的 - 因爲只要對象在附近(它應該是,由於塊將保留它默認),對象指針的本地存儲不需要放入備用存儲中,並且可以保留在堆棧上。

如果您想了解更多信息,Blocks and Variables文檔頁面詳細介紹了使用塊的內存管理以及更多有關__block存儲類型的信息。

0

這是正確的。 __block只有在您爲塊內的變量賦值(=或等效值),或者如果要阻止才能在塊創建後查看塊外部變量的賦值時才需要。 (不管變量的類型如何,這都是真的。)

這裏,變量i被分配到塊內部,其中++運算符,因此__block是必要的。變量res永遠不會分配到任何地方;變量res(未分配給)中讀取的塊。

相關問題