常見的出現(xiàn)內(nèi)存循環(huán)引用的場景有哪些?

  • 定時器(NSTimer)

NSTimer經(jīng)常被作為某個類的成員變量

@property(nonatomic,strong)NSTimer *timer;

而NSTimer一般都要指定self為target,容易造成循環(huán)引用,self->timer ->self

self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timer) userInfo:nil repeats:YES];

另外,若timer一直處于validate狀態(tài),則其引用計(jì)數(shù)器始終大于0,因此在不再使用定時器以后,應(yīng)該先調(diào)用invalidate方法, 說白了就是一定要移除定時器

  • block的使用

block在引用外部的變量是,會對外部變量進(jìn)行copy操作。在(ARC)模式下會對變量進(jìn)行強(qiáng)引用,(MRC)模式下變量retainCount加1。當(dāng)一個類把block作為成員變量時,在block內(nèi)部使用了這個類本身。造成self-->block-->self或者self-->block-->類的成員變量循環(huán)引用的情況。

解決辦法:在給block賦值時在外部用

ARC:
__weak mySelf = self;

MRC:
__block mySelf = self;

用__block修飾使用到的類。

  • 代理 delegate:

把代理設(shè)置成strong,執(zhí)行語句(self代表控制器)后,

UIScrollView *scrollView = [UIScrollView alloc] init];
scrollView.delegate = self;

當(dāng)控制器想要銷毀時,控制器被一個強(qiáng)指針指著,而scrollView添加到控制器view中也被強(qiáng)指針指著,也無法銷毀,那么它的delegate不會銷毀。delegate指向控制器。造成了循環(huán)引用。把delegate變成weak:當(dāng)控制器生命周期結(jié)束時,view隨之銷毀,內(nèi)部子空間也隨之銷毀,delegate也就銷毀了。規(guī)避該問題的殺手锏就是聲明 delegate 的時候使用 assign[MRC]或者 weak[ARC].

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容