assign 和 weak的區(qū)別
assign適用于基本數(shù)據(jù)類型,weak是適用于NSObject對(duì)象
assign其實(shí)也可以用來(lái)修飾對(duì)象,那么我們?yōu)槭裁床挥盟??因?yàn)楸籥ssign修飾的對(duì)象在釋放之后,指針的地址還是存在的,也就是說(shuō)指針并沒(méi)有被置為nil。如果在后續(xù)的內(nèi)存分配中,剛好分到了這塊地址,程序就會(huì)崩潰掉。
而weak修飾的對(duì)象在釋放之后,指針地址會(huì)被置為nil。
__weak和__block的區(qū)別
** __weak 本身是可以避免循環(huán)引用的問(wèn)題的,使用__weak修飾的變量不會(huì)在block代碼塊中被retain,但是其會(huì)導(dǎo)致外部對(duì)象釋放了之后,block 內(nèi)部也訪問(wèn)不到這個(gè)對(duì)象的問(wèn)題,我們可以通過(guò)在 block 內(nèi)部聲明一個(gè) __strong 的變量來(lái)指向 weakObj,使外部對(duì)象既能在 block 內(nèi)部保持住,又能避免循環(huán)引用的問(wèn)題。**
__block 修飾的對(duì)象會(huì)被retain(MRC下不會(huì)retain)__block本身無(wú)法避免循環(huán)引用的問(wèn)題,但是我們可以通過(guò)在 block 內(nèi)部手動(dòng)把 blockObj 賦值為 nil 的方式來(lái)避免循環(huán)引用的問(wèn)題。另外一點(diǎn)就是 __block 修飾的變量在 block 內(nèi)外都是唯一的,要注意這個(gè)特性可能帶來(lái)的隱患。
MRC模式下
使用__block能夠避免引起循環(huán)引用的問(wèn)題
ARC模式下
使用__unsafe_unretained 和 __weak都可以避免循環(huán)引用的問(wèn)題,但由于前者是unsafe的,會(huì)造成野指針問(wèn)題,所以盡量少用unsafe_unretained關(guān)鍵字 另外在多線程環(huán)境下(block中的wSelf有可能被釋放),需要先將self轉(zhuǎn)為strong指針,避免在運(yùn)行到某個(gè)關(guān)鍵步驟時(shí)self對(duì)象被釋放。
總結(jié):
- block 不是 property 時(shí),用 self 即可,不需要用weakSelf
- block 是 property,需使用 weakSelf
- block 內(nèi)多次使用 weakSelf,且有用到多執(zhí)行,需使用 strongSelf
- 不是所有 block 都得用 weakSelf (事實(shí)上多數(shù)的 iOS 原生套件,以及 GCD 的 block 是不會(huì)造成 retain cycle 的,因?yàn)樗麄儾](méi)有去 retain block)