詳解Block block迴圈引用

2021-06-29 15:49:18 字數 1792 閱讀 3240

2014-11-25 10:40

我們在block中,遇到引用外部變數,一般習慣性的給這個變數加個block 和weak 。比如block中用到self,一般都會這樣寫,

__block

__typeof

(self

)weakself

=self

;

那是不是所有的block都要用這樣寫的。這樣寫固然萬無一失吧,但是面試的時候別人問你,你就懵了,看下面**

void(^

testblock

)(void)=

^;testblock

();

如果面試者問你,這個testblock裡面的self,是否會被迴圈引用呢,為什麼?

答案是不會?為什麼呢?這要從block的三種型別說起。根據block在記憶體中的位置分為三種型別nsglobalblock,nsstackblock, nsmallocblock。

nsglobalblock:類似函式,位於text段;

nsstackblock:位於棧記憶體,函式返回後block將無效;

nsmallocblock:位於堆記憶體。

nsglobalblock如下,我們可以通過是否引用外部變數識別,未引用外部變數即為1.nsglobalblock,可以當做函式使用。

float(^

sum)(

float

,float)=

^(floata,

floatb);

nslog(@

"block is %@"

,sum

);//

block

is<

__nsglobalblock__

:0x47d0

>

2.nsstackblock,前提是mrc環境,arc

void(^

testblock

)(void)=

^;nslog(@

"block is %@",^

);//

block

is<

__nsstackblock__

:0xbfffdac0

>

//列印可看出

block

是乙個nsstackblock

,即在棧上

,當函式返回時

block

將無效nslog(@

"block is %@"

,testblock

);//

block

is<

__nsmallocblock__

:0x75425a0

>

//上面這句在非

arc中列印是

nsstackblock

,但是在

arc中就是

nsmallocblock

//即在

arc中缺省會將

block

從棧複製到堆上,而在非

arc中,則需要手動

copy

.

3.nsmallocblock只需要對nsstackblock進行copy操作就可以獲取

所以說block的迴圈引用問題,是因為block在拷貝到堆上的時候,會retain其引用的外部變數,那麼如果block中如果引用了他的宿主物件,即self,就會能引起迴圈引用。

留個問題,block被另乙個block使用時,另乙個block被copy到堆上時,被使用的block此時會被copy嗎?其引數的block是否會發生copy的.

for迴圈詳解

1 for語句,也叫迴圈語句,也稱之為for迴圈。2 for語句也是乙個結構複雜的語句,雖然簡化 如用不熟也會適得其反。3 for語句由三個部分組成 定義初始變數 迴圈條件 變化變數 for 定義初始變數 迴圈條件 變數變化 for var i 0,sum 0 i 100 console.log s...

for迴圈詳解

js一共有三種迴圈語句,今天說一說for迴圈 for迴圈一共三個值,寫法是for 定義初始變數 迴圈條件 變數變化 示例 從上面的例子中,您可以看到 statement 1 在迴圈開始之前設定變數 var i 0 statement 2 定義迴圈執行的條件 i 必須小於 j statement 3 ...

for迴圈詳解

舉例如圖下 首先for迴圈相比其他迴圈可以把條件寫在一起如圖所示 這變數,條件,變化必不可少其他迴圈也是 但是for迴圈有乙個點它在初始變數的時候,進入迴圈之前就已經執行了一次 條件是每次進入迴圈之前都會執行並且判斷 還有當continue遇到for時如圖所示 當i 5時候但是並不會進入死迴圈,因為...