1荣赶、循環(huán)引用的種類
(1)自循環(huán)引用
(2)相互循環(huán)引用
(3)多循環(huán)引用
- 如何破除循環(huán)引用拍皮?
(1)避免產(chǎn)生循環(huán)引用
(2)在合適的時機手動斷環(huán)處理 - 具體的解決方案有哪些晨缴?
(1)__weak(代理). __block(block中) __unsafe_unretain
(2)__block 在MRC下,不會增加引用計數(shù),可以避免循環(huán)引用近尚。
在ARC下,修飾對象會被強引用场勤,無法避免循環(huán)引用戈锻,需要手動斷環(huán)。
(3)__unsafe_unretain 修飾對象不會增加引用計數(shù)和媳,可以避免循環(huán)引用格遭,但是如果修飾的對象,在某一時刻被釋放留瞳,會產(chǎn)生懸垂指針拒迅,造成內(nèi)存泄漏。(不提倡使用)
- 是否遇到過循環(huán)引用她倘,又是怎樣解決的呢璧微?
(1)NSTimer 中的循環(huán)引用問題
視圖控制器中使用到了timer ,首相該對象會對timer 有一個強引用,而為timer添加回調(diào)事件后硬梁,timer對它的targate對象也有強引用前硫,這樣就出現(xiàn)了循環(huán)引用問題。同時當前線程的RunLoop對time也有一個強引用荧止。
(2)解決方案屹电?
分兩種情況:
(1)非重復的定時器:
我們可以在定時器的回調(diào)方法調(diào)用invate方法并將其置為nil.
(2)重復的定時器:
利用weak指針被釋放后,置為nil的特點跃巡。
在timer和對象之間創(chuàng)建一個中間對象危号。通過在中間對象的timer回調(diào)方法中,判斷判斷是否為空素邪,如果是外莲,就說明已經(jīng)被釋放,然后娘香,將timer設置為空苍狰。
通過創(chuàng)建一個中間對象办龄,讓中間對象分別持有兩個弱引用對象分別是timer\targate(原對象).然后timer的回調(diào)是在中間對象中進行回調(diào)的。在這個回調(diào)方法中淋昭,對targate 進行判斷,如果存在,就把timer的回調(diào)給原對象,如果不存在,就將其time設置為無效笼呆,從而解除了runloop對timer的強持有秸弛,time對中間對象的強引用關系 递览。
-
block中的循環(huán)引用問題环鲤?
解決方案:
(1)使用__weak 進行修飾
為什么使用__weak 之后西剥,就能解決循環(huán)引用呢?
因為:block對對象類型的截獲方式南捂,是連同其所有權(quán)修飾符一起進行截獲的钮蛛。所以在block中所使用的也是__weak 所修飾的甸饱。
對于__block產(chǎn)生的循環(huán)引用搞动,我們使用斷環(huán)的方式。
這種方式的弊端就是渣刷,在沒有調(diào)用Block時,該循環(huán)引用的會一直存在矗烛。斷環(huán)
6.block 為什么會產(chǎn)生循環(huán)引用辅柴?
如果block對當前對象的某一個成員變量進行截獲的話,他會連同它的所有權(quán)修飾符一起截獲瞭吃,這樣block對其就有一個強引用碌嘀。block又因為當前對象對block又一個強引用,這樣就形成了自引用方式的循環(huán)引用歪架。使用__weak 進行修飾股冗。
如果說我們使用__block ,在ARC下也會產(chǎn)生循環(huán)引用。這種情況下和蚪,使用斷環(huán)的方式止状,進行戒除循環(huán)引用。弊端:如果block不被調(diào)用攒霹,循環(huán)引用就會一直存在怯疤。