Block中weak/strong self用法
// 寫法
__weak __typeof(self)weakSelf = self;
block blk = ^() {
__strong __typeof(weakSelf)strongSelf = weakSelf;
}
_ typeof _() __typeof() 是對c語言的編譯擴(kuò)展,標(biāo)準(zhǔn)C要求會對帶有雙下劃線方法或變量進(jìn)行編譯器預(yù)處理
1.typeof()其實(shí)和上面兩者相同,typeof()本質(zhì)上是對C的擴(kuò)展,這個語法來自于C語言
weak strong 所起的作用
通常這種用法是成對出現(xiàn)的__ weak __ strong
__weak 是將變量變成弱引用,確保不會產(chǎn)生循環(huán)引用的問題。
__strong 強(qiáng)引用,則是在block整個運(yùn)行周期內(nèi)防止由于掛載對象的釋放導(dǎo)致weakSelf被釋放,導(dǎo)致的Crash。
Block詳解
Block本質(zhì)是一個函數(shù)指針,指向我們要使用的函數(shù),他可以放在棧區(qū), 堆區(qū), 靜態(tài)區(qū),都是可以被調(diào)用的。
Block有三種類型
1._NSConcreteGlobalBlock 全局靜態(tài)Block,不會訪問外部的變量,也就是說這個Block沒有對外部變量的任何引用,基本上就是打印邏輯之類或就是內(nèi)部邏輯。
2._NSConcreteStackBlock 保存在棧中的Block,當(dāng)函數(shù)返回時被銷毀,不使用copy修飾就相當(dāng)于保存在棧中的Block
3._NSConcreteMallocBlock 保存在堆中的Block,當(dāng)引用計(jì)數(shù)為0時被銷毀,使用copy修飾就會保存在堆中
全局靜態(tài)block只有在應(yīng)用被結(jié)束時才會被釋放,保存在棧中的Block他會隨著函數(shù)調(diào)用結(jié)束被銷毀,再次調(diào)用就會產(chǎn)生空指針異常。
保存在堆中的Block會隨著對象的銷毀而結(jié)束,只要對象不銷毀,我們就可以調(diào)用到在堆中的Block,它會隨著對象的銷毀而結(jié)束。
Block存儲區(qū)域問題
Block有三種存儲方式: 棧、全局、堆。Block對象中包含一個ISA屬性,可以根據(jù)該屬性哦按你算存儲位置。
注意:在ARC情況下沒有存在棧上這種情況,只有存在Global以及Malloc這兩種情況,而如果是MRC則確實(shí)存在棧、全局、堆這三種情況。
有一種比較特殊的存在棧中的Block的情況,就是僅僅只是定義了Block但是并未將其賦值給某一個變量,此時它存放在棧內(nèi)存區(qū)域,例如將定義好的的Block存放在數(shù)組中的這種情況。
全局Block
1.定義在函數(shù)外部的的Block是Global類型。
2.定義在函數(shù)內(nèi)部且沒有捕獲任何變量,那么它也是全局的。
3.有操作變量的這種Block則會存放到堆中,這個存放過程是ARC自動控制的過程。
Block的copy操作
1.棧上調(diào)用copy會復(fù)制到堆上
2.全局block調(diào)用copy什么也不做
3.堆上調(diào)用block引用計(jì)數(shù)增加 // 內(nèi)存釋放和應(yīng)用計(jì)數(shù)強(qiáng)相關(guān)