本文系轉(zhuǎn)載沟启,原文地址
ARC引入strong和weak兩個(gè)內(nèi)存管理屬性(以及__strong, __weak, __unsafe_unretained, __autoreleasing
四個(gè)變量生命期qualifier)之后谆趾,對(duì)象的delegate成員變量就面臨著對(duì)內(nèi)存管理屬性的選擇:weak or assign
眾所周知巩梢,weak屬性的變量是不為其所屬對(duì)象持有的,并且在該變量被銷毀之后知染,此weak變量的值會(huì)自動(dòng)被賦值為nil肋僧。而assign屬性一般是對(duì)C基本數(shù)據(jù)類型成員變量的聲明,當(dāng)然也可以用在對(duì)象類型成員變量上控淡,只是其代表的意義只是單純地拷貝所賦值變量的值嫌吠。即如果對(duì)某assign成員變量B賦值某對(duì)象A的指針,則此B只是簡(jiǎn)單地保存此指針的值掺炭,且并不持有對(duì)象A辫诅,也就意味著如果A被銷毀,則B就指向了一個(gè)已經(jīng)被銷毀的對(duì)象涧狮,如果再對(duì)其發(fā)送消息會(huì)引發(fā)崩潰炕矮。
但在delegate成員變量這個(gè)細(xì)分領(lǐng)域,我們即可以用weak者冤,又可以用assign肤视。因?yàn)樵趲缀跛袌?chǎng)景下,delegate所指向的對(duì)象C的生存期都是覆蓋了delegate成員變量本身所在的對(duì)象D的生存期的涉枫,所以钢颂,在D的生存期內(nèi),C所使用的D的指針都是有效的拜银,所以這個(gè)時(shí)候使用assign是沒(méi)有關(guān)系的。
舉個(gè)栗子遭垛,viewcontroller通常都會(huì)維護(hù)一個(gè)datasource對(duì)象尼桶,這種場(chǎng)景下datasource通常也會(huì)將viewcontroller的指針存儲(chǔ)在自身的delegate屬性中以供業(yè)務(wù)使用。而datasource與viewcontroller是一對(duì)一的關(guān)系锯仪,如果viewcontroller被銷毀泵督,則其對(duì)應(yīng)的datasource也就沒(méi)有存在的意義了,且viewcontroller的銷毀也會(huì)馬上引發(fā)datasource的銷毀庶喜。所以datasource的delegate成員變量?jī)?nèi)存管理屬性聲明為assign是沒(méi)有問(wèn)題的小腊,但weak屬性有一個(gè)額外的好處是如果在view controller銷毀的時(shí)候救鲤,datasource因?yàn)槿匀槐黄渌胤揭枚鴮?dǎo)致其此時(shí)并沒(méi)有跟隨view controller一起銷毀,那么此時(shí)其delegate成員變量會(huì)自動(dòng)被賦nil,相比于assign秩冈,此時(shí)它是更安全的做法本缠。