本文系轉(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ì)象持有的,并且在該變量被銷(xiāo)毀之后,此weak變量的值會(huì)自動(dòng)被賦值為nil。而assign屬性一般是對(duì)C基本數(shù)據(jù)類(lèi)型成員變量的聲明,當(dāng)然也可以用在對(duì)象類(lèi)型成員變量上,只是其代表的意義只是單純地拷貝所賦值變量的值。即如果對(duì)某assign成員變量B賦值某對(duì)象A的指針,則此B只是簡(jiǎn)單地保存此指針的值,且并不持有對(duì)象A,也就意味著如果A被銷(xiāo)毀,則B就指向了一個(gè)已經(jīng)被銷(xiāo)毀的對(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被銷(xiāo)毀,則其對(duì)應(yīng)的datasource也就沒(méi)有存在的意義了,且viewcontroller的銷(xiāo)毀也會(huì)馬上引發(fā)datasource的銷(xiāo)毀。所以datasource的delegate成員變量?jī)?nèi)存管理屬性聲明為assign是沒(méi)有問(wèn)題的,但weak屬性有一個(gè)額外的好處是如果在view controller銷(xiāo)毀的時(shí)候,datasource因?yàn)槿匀槐黄渌胤揭枚鴮?dǎo)致其此時(shí)并沒(méi)有跟隨view controller一起銷(xiāo)毀,那么此時(shí)其delegate成員變量會(huì)自動(dòng)被賦nil,相比于assign,此時(shí)它是更安全的做法。