Block的本質
- Block是將函數及其上下文封裝起來的對象
Block調用
- Block調用就是函數的調用
截獲變量
局部變量
1.基本數據類型
2.對象類型全局變量
靜態(tài)局部變量
靜態(tài)全局變量
關于Block截獲變量的特性,是否有理解?
- 對不同的數據類型,截獲方式各有不同
1.對基本數據類型的局部變量截獲其值
2.對于對象類型的局部變量連同所有權修飾符一起截獲
3.以指針方式截獲靜態(tài)局部變量
4.不截獲全局變量、靜態(tài)全局變量

輸出結果是什么呢?
在什么場景下使用__block修飾符呢?
對截獲變量進行賦值操作需要添加__block修飾符(賦值 != 使用)
對局部變量(基本數據類型和對象類型)進行賦值需要__block修飾符
-
對靜態(tài)局部變量、全局變量、靜態(tài)全局變量不需要__block修飾符
使用操作,不需要__block修飾
賦值操作,需要添加__block修飾符
添加__block修飾后,結果為8
__block修飾符起到了什么作用?__block的機制是什么?
- __block修飾變量變成了對象

__forwarding指向同類型的指針
Block的內存管理
- _NSConcreteGlobalBlock
- _NSConcreteStackBlock
-
_NSConcreteMallocBlock
不同類型的block
三種類型的block存儲區(qū)域
需要在什么時候對block進行copy操作?
- 首先明白三種類型的block進行copy有什么效果
- 對于數據區(qū)的block進行copy操作,什么也不做
- 對于棧區(qū)的block進行copy操作,在堆區(qū)產生block
- 對于堆區(qū)的block進行copy操作,會增加引用計數
- 生命周期
-
對于棧區(qū)的block,變量作用域結束,隨之銷毀
在MRC環(huán)境下,對棧區(qū)的block進行copy操作,不作處理會產成內存泄漏
__forwarding總結
- 不管在任何內存位置,都可以順利的訪問同一個__block變量
Block循環(huán)引用(為什么會產生循環(huán)引用)在下圖中,有什么問題?如何解決?

示例
- 產生自循環(huán)引用 因為當前對象通過copy聲明block,而在當前block中又使用到了當前對象的成員變量,因為會連帶屬性關鍵字一起截獲,因為array是通過strong修飾,因此block中有一個strong類型的指針指向當前對象,產生循環(huán)引用
- 解決方法:避免循環(huán)引用——在當前棧中用__weak修飾的weakArray指針指向原對象的_array,在block中使用weakArray(因為截獲的是一個__weak類型)
(__block造成的循環(huán)引用)在下圖中,有什么問題?如何解決?

示例
- 在MRC中,不會產生循環(huán)引用
-
在ARC中,產生循環(huán)引用,引起內存泄漏
解決方案,斷環(huán) 但是如果一直不調用block,環(huán)就一直存在






