block用法和疑問

2021-06-21 14:37:38 字數 2191 閱讀 3554

本文主要是闡述一下block中如何的使用外部變數以及block本身的記憶體管理。

先定義乙個block變數,作為後續的例子中使用:

typedef void(^blockcc)(void); 

blockcc _block; 

1、block中引用外部變數

block中可以直接使用外部的變數,比如

int number = 1; 

_block = ^(); 

那麼實際上,在block生成的時候,是會把number當做是

常量變數

編碼到block當中。可以看到,以下的**,block中的number值是不會發生變化的:

int number = 1; 

_block = ^(); 

number = 2; 

_block(); 

則輸出的值為 1,而不是2。原因就是如上所說。

如果要在block中嘗試改變外部變數的值,則會報錯的。對於這個問題的解決辦法是引入__block識別符號。將需要在block內部修改的變數標識為__block scope。更改後的**如下:

__block int number = 1; 

_block = ^(); 

這個時候,其實block外部的number和block內部的number指向了同乙個值,回到剛才的在外部改變block的例子,它的輸出結果將是2,而不是1。有興趣的可以自己寫乙個例子試試。

2、block自身的記憶體管理

block本身是像物件一樣可以retain,和release。但是,block在建立的時候,它的記憶體是分配在棧(stack)上,而不是在堆(heap)上。它

本身的作用域是屬於建立時候的作用域,一旦在建立時候的作用域外面呼叫block將導致程式崩潰。比如下面的例子。

我在view did load中建立了乙個block:

- (void)viewdidload 

; } 

並且在乙個按鈕的事件中呼叫了這個block:

- (ibaction)testdidclick:(id)sender  

此時我按了按鈕之後就會導致程式崩潰,解決這個問題的方法就是在建立完block的時候需要呼叫copy的方法。copy會把block從棧上移動到堆上,那麼就可以在其他地方使用這個block了~

修改**如下:

_block = ^(); 

_block = [_block copy]; 

同理,特別需要注意的地方就是在把block放到集合類當中去的時候,如果直接把生成的block放入到集合類中,是無法在其他地方使用block,必須要對block進行copy。不過**看上去相對奇怪一些:

[array addobject:[[^ copy] autorelease]]; 

3、迴圈引用

這一點其實是在第一點的乙個小的衍生。當在block內部使用成員變數的時候,比如

@inte***ce viewcontroller : uiviewcontroller 

@end 

在block建立中:

_block = ^(); 

這裡的_string相當於是self->_string;那麼block是會對內部的物件進行一次retain。也就是說,self會被retain一次。當self釋放的時候,需要block釋放後才會對self進行釋放,但是block的釋放又需要等self的dealloc中才會釋放。如此一來變形成了迴圈引用,導致記憶體洩露。

修改方案是新建乙個__block scope的區域性變數,並把self賦值給它,而在block內部則使用這個區域性變數來進行取值。因為__block標記的變數是不會被自動retain的

__block viewcontroller *controller = self; 

_block = ^(); 

block用法小計

預設情況下,任何block都是在棧中,隨時可能會被 對block設定copy屬性,block的記憶體就會放到堆裡面。book b book alloc init b.block 如果像上述寫法block所指向的 塊會強引用book的記憶體位址,使得book物件不能釋放,造成記憶體洩露。book b ...

block 基本用法

專門處理 需要重複呼叫的 block 返回值相同,引數相同 在.h檔案中,宣告 typedef void typedefblock nsstring typedef int typedefbock2 inta,intb ibaction testaction id sender oc語言 self ...

Block用法解析

block 塊是對c做出的乙個補充,初次體驗 塊,無比的不適應。古怪的語法確實讓人不易入門甚至精通。但若能夠深入精通block的使用,會給 帶來層次上的提公升。block就是一段在將來被執行的 塊返回值型別 形參型別1 形參1,形參型別2 形參2,塊返回值型別 塊變數名 形參型別1,形參型別2,定義...