iOS 內(nèi)存管理的一點(diǎn)小問題

現(xiàn)在大家的項(xiàng)目應(yīng)該基本都是ARC了,如果還是MRC的話奈虾,趕緊轉(zhuǎn)換到ARC吧肆汹!最近被臨時(shí)拉過去開發(fā)iPad,由于項(xiàng)目原因昂勉,還是使用的MRC。今天在調(diào)部分界面的時(shí)候村象,發(fā)現(xiàn)一段代碼攒至,我怎么看都怎么覺得怪怪的,因?yàn)槭荕RC嘛迫吐!所以我心里還是一直提醒著自己。仔細(xì)一看還真是不對(duì)熙宇,這段代碼給周圍同事看的時(shí)候,也不是每個(gè)人都能一眼看出問題烫止,因?yàn)榇蠹乙呀?jīng)習(xí)慣了ARC或者沒有在MRC下進(jìn)行開發(fā)過。

下面我貼出類似的代碼:

- (void)pushVc
{
    pushVC = [[UIViewController alloc] init];

    [self.navigationController pushViewController:pushVC animated:YES];
}

以上這段代碼很簡單期升,就是有個(gè)UIViewController類型的成員變量pushVC互躬,然后創(chuàng)建一個(gè)VC賦值給他,最后push到這個(gè)頁面行拢〉ǎ可能很多人一看竭缝,這代碼就是平常自己寫的啊,都沒有出現(xiàn)過問題啊抬纸。如果這段代碼是在ARC下,是沒有任何問題的阿趁。但是坛猪,如果我們的代碼是在MRC下,會(huì)出現(xiàn)什么問題呢命黔?如果經(jīng)歷過MRC開發(fā)的人就斤,肯定也會(huì)覺得這邊怪怪的。至少?zèng)]有發(fā)現(xiàn)調(diào)用release洋机。由于pushVC是成員變量,所以一定程度上也迷惑了下同事喜鼓。上面的代碼其實(shí)已經(jīng)內(nèi)存泄露了。[[UIViewController alloc] init] 這個(gè)方法創(chuàng)建出來的對(duì)象將不會(huì)被銷毀颠通,一直留在內(nèi)存中。為什么谨垃?這個(gè)對(duì)象創(chuàng)建出來的時(shí)候引用是1硼控,然后經(jīng)過push引用計(jì)數(shù)已經(jīng)變成2了。當(dāng)這個(gè)vc在后面被pop出來的時(shí)候牢撼,引用計(jì)數(shù)會(huì)減1,這時(shí)這個(gè)VC的引用計(jì)數(shù)還是1纷责。在內(nèi)存中將銷毀不掉撼短。如果這個(gè)方法被多次調(diào)用的話,將會(huì)出現(xiàn)大量的這個(gè)對(duì)象在內(nèi)存中喂柒。

下面再說一個(gè)知識(shí)點(diǎn)禾嫉,很多人知道,但是并不一定完全了解我們的@property到底做了什么熙参。


- (void)pushVc
{
    self.pushVC = [[UIViewController alloc] init];

    [self.navigationController pushViewController:pushVC animated:YES];
}

在看這段代碼,我給成員變量賦值的方式換成了self.pushVC,這個(gè)和直接賦值有什么區(qū)別呢讲竿?如果你調(diào)用self.pushVC進(jìn)行賦值弄屡,那么這個(gè)時(shí)候會(huì)調(diào)用系統(tǒng)為我們默認(rèn)生成的setter方法。這個(gè)setter會(huì)幫我們做內(nèi)存的引用計(jì)數(shù)操作膀捷。看下系統(tǒng)生成的方法示例:

- (void)setPushVC:(UIViewController *)setPushVC
{
    [setPushVC retain];
    [pushVC release];
    pushVC = setPushVC;
}

首先秀仲,系統(tǒng)會(huì)將傳進(jìn)來的對(duì)象引用計(jì)數(shù)加1,之后將賦值的對(duì)象引用計(jì)數(shù)減1雁刷,最后再給對(duì)象賦值保礼。記得自己重寫setter方法的時(shí)候,一定要先將傳進(jìn)來的對(duì)象做下retain操作炮障,之后在release本身的對(duì)象。如果你代碼這樣寫的話:

- (void)setPushVC:(UIViewController *)setPushVC
{
    [pushVC release];
    [setPushVC retain];
    pushVC = setPushVC;
}

正常情況下是沒有問題的企蹭,但是如果是自己給自己賦值的話self.pushVC = pushVC智末,那就有問題了。當(dāng)然你可以做下if判斷螟凭,兩個(gè)對(duì)象是否一樣它呀,那樣也行棒厘。

接下來看下這個(gè)代碼的正確寫法:

    UIViewController *VC = [[UIViewController alloc] init];
    pushVC = [VC retain];
    [VC release];
    [self.navigationController pushViewController:VC animated:YES];
    //或者
    UIViewController *VC = [[UIViewController alloc] init];
    self.pushVC = VC
    [VC release];
    [self.navigationController pushViewController:VC animated:YES];

建議大家在MRC下使用成員變量的時(shí)候最好使用self.setter方法。有同事又提出了另一種寫法:

    pushVC = [[[UIViewController alloc] init] autorelease];

    [self.navigationController pushViewController:pushVC animated:YES];

autorelease,但是這樣寫有個(gè)問題谓媒,一旦你使用這個(gè)關(guān)鍵字何乎,那你就不在有這個(gè)創(chuàng)建對(duì)象的內(nèi)存管理權(quán),系統(tǒng)會(huì)在之后的某個(gè)時(shí)間支救,對(duì)其進(jìn)行release操作。這樣也違背了用成員變量保存這個(gè)VC的意圖指孤。

總結(jié)

很多同事一眼沒有看出來,是因?yàn)槲覀円呀?jīng)習(xí)慣了ARC恃轩,認(rèn)為=就是給對(duì)象進(jìn)行了retain。在ARC下默認(rèn)變量前面都有一個(gè)隱藏的__strong松忍。在ARC下只要變量指向?qū)ο罂昀澹敲聪到y(tǒng)會(huì)我們自動(dòng)的對(duì)那個(gè)對(duì)象進(jìn)行retain操作,當(dāng)我們將對(duì)象置為nil的時(shí)候叽掘,系統(tǒng)會(huì)默認(rèn)給我們做release操作玖雁。

引用計(jì)數(shù)內(nèi)存管理的思考方式:

  • 自己生成的對(duì)象,自己所持有
  • 非自己生成的對(duì)象赫冬,自己也恩能持有
  • 自己持有的對(duì)象不再需要時(shí)釋放
  • 非自己持有的對(duì)象無法釋放

當(dāng)我們使用ARC的時(shí)候,也是遵循了上面的思考方式膛薛。不要因?yàn)槲覀儧]有看到retain或者release而認(rèn)為管理方式變了或者不需要內(nèi)存管理了补鼻。ARC看起來很簡單,因?yàn)樘O果把那些引用計(jì)數(shù)的操作代碼都交給了編譯器咨跌,所以給了我們這種錯(cuò)覺硼婿。了解MRC,可以加深自己對(duì)ARC的理解寇漫。不至于讓自己被ARC給蒙蔽了。

使用ARC可以讓我們的代碼更加精簡记焊,健壯栓撞,特別是weak這個(gè)關(guān)鍵字,更是解決了野指針的問題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肛响,一起剝皮案震驚了整個(gè)濱河市惜索,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌猎物,老刑警劉巖角塑,帶你破解...
    沈念sama閱讀 223,126評(píng)論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異堤如,居然都是意外死亡窒朋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門榔至,熙熙樓的掌柜王于貴愁眉苦臉地迎上來欺劳,“玉大人,你說我怎么就攤上這事划提。” “怎么了?”我有些...
    開封第一講書人閱讀 169,941評(píng)論 0 366
  • 文/不壞的土叔 我叫張陵掸犬,是天一觀的道長绪爸。 經(jīng)常有香客問我,道長奠货,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,294評(píng)論 1 300
  • 正文 為了忘掉前任柔滔,我火速辦了婚禮,結(jié)果婚禮上形真,老公的妹妹穿的比我還像新娘超全。我一直安慰自己,他們只是感情好嘶朱,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評(píng)論 6 398
  • 文/花漫 我一把揭開白布疏遏。 她就那樣靜靜地躺著,像睡著了一般改览。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上视事,一...
    開封第一講書人閱讀 52,874評(píng)論 1 314
  • 那天庆揩,我揣著相機(jī)與錄音,去河邊找鬼虏辫。 笑死锈拨,一個(gè)胖子當(dāng)著我的面吹牛砌庄,可吹牛的內(nèi)容都是我干的奕枢。 我是一名探鬼主播,決...
    沈念sama閱讀 41,285評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼萌焰,長吁一口氣:“原來是場噩夢啊……” “哼谷浅!你這毒婦竟也來了奶卓?” 一聲冷哼從身側(cè)響起撼玄,我...
    開封第一講書人閱讀 40,249評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤互纯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后留潦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體繁堡,經(jīng)...
    沈念sama閱讀 46,760評(píng)論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡倒源,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評(píng)論 3 343
  • 正文 我和宋清朗相戀三年孵稽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了十偶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,973評(píng)論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡接校,死狀恐怖狮崩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情诽凌,我是刑警寧澤坦敌,帶...
    沈念sama閱讀 36,631評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站狱窘,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏哑舒。R本人自食惡果不足惜幻馁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望膘滨。 院中可真熱鬧稀拐,春花似錦火邓、人聲如沸德撬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽隆檀。三九已至,卻和暖如春泉坐,著一層夾襖步出監(jiān)牢的瞬間裳仆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評(píng)論 1 275
  • 我被黑心中介騙來泰國打工记某, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留构捡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,431評(píng)論 3 379
  • 正文 我出身青樓勾徽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親畅姊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吹由,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評(píng)論 2 361

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

  • 內(nèi)存管理 簡述OC中內(nèi)存管理機(jī)制。與retain配對(duì)使用的方法是dealloc還是release粗合,為什么?需要與a...
    丶逐漸閱讀 1,974評(píng)論 1 16
  • iOS內(nèi)存管理 概述 什么是內(nèi)存管理 應(yīng)用程序內(nèi)存管理是在程序運(yùn)行時(shí)分配內(nèi)存(比如創(chuàng)建一個(gè)對(duì)象,會(huì)增加內(nèi)存占用)與...
    蚊香醬閱讀 5,732評(píng)論 8 119
  • 內(nèi)存管理 ARC處理原理 ARC是Objective-C編譯器的特性,而不是運(yùn)行時(shí)特性或者垃圾回收機(jī)制供屉,ARC所做...
    b485c88ab697閱讀 11,217評(píng)論 3 47
  • 概述 在iOS中開發(fā)中,我們或多或少都聽說過內(nèi)存管理悼做。iOS的內(nèi)存管理一般指的是OC對(duì)象的內(nèi)存管理哗魂,因?yàn)镺C對(duì)象分...
    DamonMok閱讀 4,006評(píng)論 2 20
  • 今天聽了紅點(diǎn)情商管理的課程,感覺問題方法千千萬啡彬,雖然我還是對(duì)于自己方向不是特別清晰,但對(duì)于現(xiàn)階段來講纵搁,有一句話很打...
    敏尓閱讀 185評(píng)論 1 0