IBOutlet屬性應(yīng)該用Strong還是Weak來(lái)修飾轿曙?

結(jié)論:

雖然現(xiàn)在用weak還是strong并沒(méi)有什么實(shí)質(zhì)性差別袒哥,但是除非是有特定需要避免循環(huán)引用才用weak,否則按照蘋(píng)果官方的觀(guān)點(diǎn)豆励,目前對(duì)于IBOutlet的最佳實(shí)踐應(yīng)該是使用strong

起因:

最近用SwiftFormat工具來(lái)格式化swift代碼夺荒,有個(gè)現(xiàn)象引起了我的興趣:

用這個(gè)工具格式化的swift代碼了里面的IBOutlet屬性里面的weak修飾符都消失了,也就是它在格式化的時(shí)候把IBOutlet屬性變成了用strong修飾良蒸。

正巧最近新公司發(fā)了電腦技扼,新安裝了Xcode,發(fā)現(xiàn)新安裝的Xcode拖IBOutlet屬性也是默認(rèn)選擇strong嫩痰。

在之前的開(kāi)發(fā)中我一直以為IBOutlet默認(rèn)就應(yīng)該是weak剿吻,從沒(méi)考慮過(guò)strong情況,但是這兩個(gè)肯定不是巧合串纺,其內(nèi)在應(yīng)該是有原因的丽旅。

研究:

其實(shí)這個(gè)問(wèn)題在StackOverFlow里早就有相關(guān)話(huà)題和討論結(jié)果:

Should IBOutlet be strong or weak under ARC?

stackoverflow.jpg

大意就是:

蘋(píng)果建議除非是有特定需要避免循環(huán)引用才使用weak,否則目前對(duì)于IBOutlet的最佳實(shí)踐應(yīng)該是使用strong
WWDC 2015的”Implementing UI Designs in Interface Builder”會(huì)議,則有個(gè)Apple的工程師說(shuō):
“通常你應(yīng)該用strong來(lái)修飾你的outlet,尤其是當(dāng)你要連接一個(gè)outlet到子視圖或者在視圖層次中不總是被持有的constraint(約束?)時(shí).只有當(dāng)你用自定義的視圖來(lái)引用一個(gè)東東,而這個(gè)東東反過(guò)來(lái)又引用了視圖層次時(shí)才需要用weak,但還是不推薦這么做.”

同時(shí)回答者在Twitter上詢(xún)問(wèn)了蘋(píng)果的IB團(tuán)隊(duì)的一個(gè)工程師確認(rèn)了這個(gè)事情纺棺。

那具體到用weakstrong到底有什么區(qū)別呢榄笙?

我們?cè)贗nterfaceBuilder里面往ViewController里拖一個(gè)label時(shí),這個(gè)label是加到了這個(gè)ViewController的view上祷蝌,view有一個(gè)subViews屬性茅撞,這個(gè)屬性是一個(gè)數(shù)組,里面是這個(gè)view的所有子view巨朦,而我們加的控件就位于這個(gè)數(shù)組中米丘,所以實(shí)際上我們的控件對(duì)象是屬于view的,也就是說(shuō)view對(duì)加到它上面的控件是強(qiáng)引用糊啡。我們往ViewController里面拖屬性時(shí)如果使用weak或者strong修飾拄查,引用關(guān)系分別如下圖(實(shí)線(xiàn)箭頭代表強(qiáng)引用,虛線(xiàn)箭頭代表弱引用):

引用.jpg

從圖上可以看出來(lái)棚蓄,這兩種修飾方式其實(shí)差別不大堕扶,唯一的區(qū)別在于如果中間的view變成了nil,label是否會(huì)被釋放

如果是weak修飾梭依,view變成了nil時(shí)稍算,label只有VC的弱引用,沒(méi)有被強(qiáng)引用了睛挚,就會(huì)被系統(tǒng)釋放
如果是strong修飾邪蛔,view變成了nil時(shí),label還被VC強(qiáng)引用扎狱,所以不會(huì)被釋放

那問(wèn)題來(lái)了侧到,什么情況下一個(gè)ViewController的view會(huì)被變成nil呢勃教?

這要追溯到早期的iOS版本了,在iOS6之前匠抗,ViewController生命周期里有個(gè)viewDidUnload方法故源,開(kāi)發(fā)時(shí)間比較久的開(kāi)發(fā)者或者是在一些過(guò)時(shí)的面試題中會(huì)看到這個(gè)方法,它的作用是:

In iOS 5 and earlier, when a low-memory condition occurred and the current view controller's views were not needed, the system could opt to call this method after the view controller's view had been released. This method was your chance to perform any final cleanup. If your view controller stored separate references to the view or its subviews, you could use this method to release those references. You could also use this method to remove references to any objects that you created to support the view but that are no longer needed now that the view is gone. You would not use this method to release user data or any other information that cannot be easily recreated.
In iOS 6 and later, clearing references to views and other objects in your view controller is unnecessary.
At the time this method is called, the view property is nil.

簡(jiǎn)單說(shuō)就是iOS6之前汞贸,當(dāng)系統(tǒng)內(nèi)存過(guò)低時(shí)绳军,系統(tǒng)會(huì)自動(dòng)釋放掉已經(jīng)不需要用到的VC的view,當(dāng)這個(gè)VC的view被Release之后矢腻,就會(huì)調(diào)用viewDidUnload方法门驾,如果開(kāi)發(fā)者在VC里面存儲(chǔ)了對(duì)view或其subviews的單獨(dú)引用,則需要在這個(gè)方法里面釋放掉這些引用多柑。

也就是說(shuō)奶是,蘋(píng)果認(rèn)為如果VC的view被release了,那么它引用的subviews同樣應(yīng)該被release竣灌。結(jié)合上面的圖來(lái)看聂沙,如果用weak修飾label,那么label的生命周期就和view一樣初嘹,view為nil及汉,label也會(huì)自動(dòng)為nil,而用strong修飾IBOutlet屯烦,label不會(huì)自動(dòng)被釋放坷随,開(kāi)發(fā)者需要自己在viewDidUnload方法里面手動(dòng)把label置為nil。相比之下漫贞,還是前一種方法簡(jiǎn)潔省事甸箱,所以我認(rèn)為蘋(píng)果官方當(dāng)時(shí)建議使用weak來(lái)修飾應(yīng)該是出于這個(gè)原因育叁。

這也是有時(shí)代背景的迅脐,早期iPhone內(nèi)存都比較小,為了把內(nèi)存利用到極致豪嗽,要盡力去優(yōu)化每個(gè)app的內(nèi)存占用谴蔑,所以在VC的生命周期里面設(shè)計(jì)了這么一個(gè)viewDidUnload方法,而到了2011龟梦、2012年隐锭,內(nèi)存翻倍了以后,可能蘋(píng)果通過(guò)評(píng)估和監(jiān)測(cè)计贰,發(fā)現(xiàn)viewDidUnload已經(jīng)極少被觸發(fā)钦睡,即使low-memory被觸發(fā),系統(tǒng)也可以通過(guò)其他方式騰挪出更多內(nèi)存給前臺(tái)app(我推測(cè)的)躁倒。所以在iOS6的時(shí)候蘋(píng)果認(rèn)為這個(gè)方法已經(jīng)沒(méi)用了荞怒,就廢棄了這個(gè)方法洒琢。

而iOS6之后,VC的view再也不會(huì)被系統(tǒng)自動(dòng)release了褐桌,我們作為開(kāi)發(fā)者衰抑,什么情況下會(huì)去主動(dòng)把VC的view置為nil呢?個(gè)人覺(jué)得基本不會(huì)有這樣的操作荧嵌,在我?guī)啄甑拈_(kāi)發(fā)工作中還沒(méi)有遇到呛踊,也想不到有什么場(chǎng)景下是需要保留VC而單獨(dú)把view置nil的。所以在此時(shí)用weak修飾IBOutlet的內(nèi)在要求已經(jīng)消失了啦撮,在view不可能為nil的情況下谭网,用weak還是strong已經(jīng)沒(méi)有什么區(qū)別,無(wú)論是用weak還是strong修飾赃春,IBOutlet屬性的生命周期都是一樣的蜻底。實(shí)際上我在之前的開(kāi)發(fā)中一直是使用weak來(lái)修飾的,并沒(méi)有因?yàn)檫`背蘋(píng)果的推薦做法而出問(wèn)題聘鳞。

那按照蘋(píng)果建議使用strong修飾有什么好處呢薄辅?
……
好像沒(méi)有。因?yàn)槟壳翱磥?lái)使用weak還是strong沒(méi)有區(qū)別抠璃。
不過(guò)既然必須使用weak的理由沒(méi)有了站楚,蘋(píng)果官方又建議使用strong(雖然沒(méi)有在文檔里明說(shuō),但是從新下載的Xcode默認(rèn)是strong搏嗡,以及IB團(tuán)隊(duì)的工程師的說(shuō)法佐證)窿春,那么我們還是盡量使用strong,跟著官方的建議走采盒。如果未來(lái)蘋(píng)果要在這個(gè)地方做文章旧乞,比如對(duì)IBOutlet做一些優(yōu)化,那肯定也是按照strong為前提來(lái)做的磅氨,我們的代碼不會(huì)出問(wèn)題尺栖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市烦租,隨后出現(xiàn)的幾起案子延赌,更是在濱河造成了極大的恐慌,老刑警劉巖叉橱,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挫以,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡窃祝,警方通過(guò)查閱死者的電腦和手機(jī)掐松,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人大磺,你說(shuō)我怎么就攤上這事泻仙。” “怎么了量没?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵玉转,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我殴蹄,道長(zhǎng)究抓,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任袭灯,我火速辦了婚禮刺下,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘稽荧。我一直安慰自己橘茉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布姨丈。 她就那樣靜靜地躺著畅卓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蟋恬。 梳的紋絲不亂的頭發(fā)上翁潘,一...
    開(kāi)封第一講書(shū)人閱讀 51,482評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音歼争,去河邊找鬼拜马。 笑死,一個(gè)胖子當(dāng)著我的面吹牛沐绒,可吹牛的內(nèi)容都是我干的俩莽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼乔遮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼扮超!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起申眼,我...
    開(kāi)封第一講書(shū)人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瞒津,失蹤者是張志新(化名)和其女友劉穎蝉衣,沒(méi)想到半個(gè)月后括尸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡病毡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年濒翻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡有送,死狀恐怖淌喻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情雀摘,我是刑警寧澤裸删,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站阵赠,受9級(jí)特大地震影響涯塔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜清蚀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一匕荸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧枷邪,春花似錦榛搔、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至嘶卧,卻和暖如春童本,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背脸候。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工穷娱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人运沦。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓泵额,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親携添。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嫁盲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類(lèi)型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,101評(píng)論 1 32
  • 對(duì)于純代碼布局,用@property聲明成員變量時(shí)烈掠,我是很自然的用strong來(lái)修飾的羞秤。然后突然有人問(wèn)我用weak...
    幽玄727閱讀 778評(píng)論 0 1
  • 一、深復(fù)制和淺復(fù)制的區(qū)別左敌? 1瘾蛋、淺復(fù)制:只是復(fù)制了指向?qū)ο蟮闹羔槪磧蓚€(gè)指針指向同一塊內(nèi)存單元矫限!而不復(fù)制指向?qū)ο蟮?..
    iOS_Alex閱讀 1,376評(píng)論 1 27
  • 1.OC里用到集合類(lèi)是什么哺哼? 基本類(lèi)型為:NSArray佩抹,NSSet以及NSDictionary 可變類(lèi)型為:NS...
    輕皺眉頭淺憂(yōu)思閱讀 1,374評(píng)論 0 3
  • 親愛(ài)的寶媽寶爸: 今天我們共同探討:怎樣說(shuō)茵汰,才能使孩子更配合枢里? 請(qǐng)大家一起回憶,是否遇到過(guò)以下類(lèi)似的場(chǎng)景蹂午? 1.當(dāng)...
    一片清新自留地閱讀 368評(píng)論 0 2