在OC中行您, block代碼塊有三種不同類型糯崎。
1._NSConcreteGlobalBlock
全局的靜態(tài)block果复,不會訪問外部的變量濒翻。就是說block沒有調用其他的外部變量互例。
2._NSConcreteStackBlock
保存在棧中的 block葫辐,當函數(shù)返回時會被銷毀蹬挺。這個block就是沒有被賦值唬滑,并且block訪問了外部變量聂示。
3._NSConcreteMallocBlock
保存在堆中的 block域携,當引用計數(shù)為 0 時會被銷毀,對_NSConcreteStackBlock 執(zhí)行copy得來的鱼喉。
block 使用copy 修飾的原因:
我們知道秀鞭,函數(shù)的聲明周期是隨著函數(shù)調用的結束就終止了。我們的block是寫在函數(shù)中的扛禽。
如果是全局靜態(tài)block的話锋边,他直到程序結束的時候,才會被被釋放编曼。但是我們實際操作中基本上不會使用到不訪問外部變量的block(_NSConcreteGlobalBlock)豆巨。
如果是保存在棧中的block,他會隨著函數(shù)調用結束被銷毀掐场。從而導致我們在執(zhí)行一個包含block的函數(shù)之后往扔,就無法再訪問這個block。因為(函數(shù)結束熊户,函數(shù)棧就銷毀了萍膛,存在函數(shù)里面的block也就沒有了),我們再使用block時嚷堡,就會產(chǎn)生空指針異常(_NSConcreteStackBlock)蝗罗。
如果是堆中的block,也就是copy修飾的block。他的生命周期就是隨著對象的銷毀而結束的串塑。只要對象不銷毀沼琉,我們就可以調用的到在堆中的block(_NSConcreteMallocBlock)。
這就是為什么我們要用copy來修飾block拟赊。因為不用copy修飾的訪問外部變量的block刺桃,只在他所在的函數(shù)被調用的那一瞬間可以使用。之后就消失了吸祟。
block 什么時候被自動copy
作為變量:
一個 block 剛聲明的時候是在棧上
賦值給一個普通變量之后就會被 copy 到堆上
賦值給一個 weak 變量不會被 copy
函數(shù)傳參:
作為參數(shù)傳入函數(shù)? block不會被 copy
作為函數(shù)的返回值? block會被 copy
針對 block 做為參數(shù) 傳入函數(shù) block 不會被copy瑟慈,這些知名的開源庫是這么做的
這里寫圖片描述