談談iOS開發(fā)的內(nèi)存管理

iOS內(nèi)存管理機制的原理是引用計數(shù)厢岂,引用計數(shù)簡單來說就是統(tǒng)計一塊內(nèi)存的所有權(quán),當這塊內(nèi)存被創(chuàng)建出來的時候阳距,它的引用計數(shù)從0增加到1塔粒,表示有一個對象或指針持有這塊內(nèi)存筐摘,擁有這塊內(nèi)存的所有權(quán),如果這時候有另外一個對象或指針指向這塊內(nèi)存咖熟,那么為了表示這個后來的對象或指針對這塊內(nèi)存的所有權(quán),引用計數(shù)加1變?yōu)?馍管,之后若有一個對象或指針不再指向這塊內(nèi)存時,引用計數(shù)減1捌锭,表示這個對象或指針不再擁有這塊內(nèi)存的所有權(quán),當一塊內(nèi)存的引用計數(shù)變?yōu)?观谦,表示沒有任何對象或指針持有這塊內(nèi)存宛逗,系統(tǒng)便會立刻釋放掉這塊內(nèi)存盾剩。

其中在開發(fā)時引用計數(shù)又分為ARC(自動內(nèi)存管理)和MRC(手動內(nèi)存管理)替蔬。ARC的本質(zhì)其實就是MRC屎暇,只不過是系統(tǒng)幫助開發(fā)者管理已創(chuàng)建的對象或內(nèi)存空間,自動在系統(tǒng)認為合適的時間和地點釋放掉已經(jīng)失去作用的內(nèi)存空間根悼,原理是一樣的。雖然ARC操作起來很方便挤巡,不但減少了代碼量,而且降低了內(nèi)存出錯的概率喉恋,但因為ARC不一定會及時釋放母廷,所以程序有時候可能會占用內(nèi)存較大轻黑。而MRC若做得好,通過手動管理琴昆,及時釋放掉不需要的內(nèi)存空間,便可保證程序長時間運行在良好狀態(tài)上抖拦。

在MRC中會引起引用計數(shù)變化的關(guān)鍵字有:alloc舷暮,retain,copy脚牍,release,autorelease券膀。(strong關(guān)鍵字只用于ARC驯遇,作用等同于retain)

alloc:當一個類的對象創(chuàng)建,需要開辟內(nèi)存空間的時候叉庐,會使用alloc,alloc是一個類方法玩郊,只能用類調(diào)用,它的作用是開辟一塊新的內(nèi)存空間译红,并使這塊內(nèi)存的引用計數(shù)從0增加到1,注意耻陕,是新的內(nèi)存空間刨沦,每次用類alloc出來的都是一塊新的內(nèi)存空間,與上一次alloc出來的內(nèi)存空間沒有必然聯(lián)系想诅,而且上一次alloc出來的內(nèi)存空間仍然存在,不會被釋放侧蘸。

retain:retain是一個實例方法,只能由對象調(diào)用穿稳,它的作用是使這個對象的內(nèi)存空間的引用計數(shù)加1晌坤,并不會新開辟一塊內(nèi)存空間,通常于賦值是調(diào)用它改,如:

對象2=[對象1 retain]商乎;表示對象2同樣擁有這塊內(nèi)存的所有權(quán)。若只是簡單地賦值鹉戚,如:對象2=對象1;那么當對象1的內(nèi)存空間被釋放的時候遏餐,對象2便會成為野指針,再對對象2進行操作便會造成內(nèi)存錯誤失都。

copy:copy同樣是一個實例方法,只能由對象調(diào)用咳焚,返回一個新的對象信粮,它的作用是復制一個對象到一塊新的內(nèi)存空間上趁啸,舊內(nèi)存空間的引用計數(shù)不會變化,新的內(nèi)存空間的引用計數(shù)從0增加到1不傅,也就是說,雖然內(nèi)容一樣商虐,但實質(zhì)上是兩塊內(nèi)存崖疤,相當于克隆,一個變成兩個劫哼。其中copy又分為淺拷貝、深拷貝和真正的深拷貝眯亦,淺拷貝只是拷貝地址與retain等同般码;深拷貝是拷貝內(nèi)容,會新開辟新內(nèi)存板祝,與retain不一樣;真正的深拷貝是對于容器類來說的囊嘉,如數(shù)組類革为、字典類和集合類(包括可變和不可變),假設有一個數(shù)組類對象震檩,普通的深拷貝會開辟一塊新內(nèi)存存放這個對象蜓堕,但這個數(shù)組對象里面的各個元素的地址卻沒有改變也就是說數(shù)組元素只是進行了retain或者淺拷貝而已博其,并沒有創(chuàng)建新的內(nèi)存空間,而真正的深拷貝背伴,不但數(shù)組對象本身進行了深拷貝峰髓,連數(shù)組元素都進行了深拷貝,即為各個數(shù)組元素開辟了新的內(nèi)存空間携兵。

release:release是一個實例方法,同樣只能由對象調(diào)用静檬,它的作用是使對象的內(nèi)存空間的引用計數(shù)減1并级,若引用計數(shù)變?yōu)?則系統(tǒng)會立刻釋放掉這塊內(nèi)存。如果引用計數(shù)為0的基礎上再調(diào)用release嘲碧,便會造成過度釋放,使內(nèi)存崩潰钉迷;

autorelease:autorelease是一個實例方法钠署,同樣只能由對象調(diào)用,它的作用于release類似谐鼎,但不是立刻減1狸棍,相當于一個延遲的release,通常用于方法返回值的釋放草戈,如便利構(gòu)造器。autorelease會在程序走出自動釋放池時執(zhí)行丙猬,通常系統(tǒng)會自動生成自動釋放池(即使是MRC下),也可以自己設定自動釋放池茧球。

除了以上所述的關(guān)鍵字,還有一些方法會引起引用計數(shù)的變化弹灭,如UI中父視圖添加揪垄、移除子視圖,導航控制器或視圖控制器推出新的視圖控制器以及返回福侈,容器類(數(shù)組卢未、字典和集合)添加和移除元素。

當子視圖添加到父視圖上時伟墙,子視圖的引用計數(shù)加1滴铅,移除時引用計數(shù)減1,若父視圖引用計數(shù)變?yōu)?內(nèi)存被釋放汉匙,其所有的子視圖都會被release一次,即引用計數(shù)減1戏自,原則上只有這三種情況子視圖的引用計數(shù)會發(fā)生變化伤锚,其他如父視圖引用計數(shù)的加減都不會影響到子視圖。

容器類的情況與視圖類似猛们,添加元素狞洋,該元素引用計數(shù)加1,移除元素吉懊,該元素引用計數(shù)減1惯吕,容器引用計數(shù)變?yōu)?所占用內(nèi)存被釋放怕午,容器所有元素release,引用計數(shù)減1堡距,其他情況下容器本身的引用計數(shù)變化不會影響到容器內(nèi)元素的引用計數(shù)變化兆蕉。

文/且行且珍惜_iOS(簡書作者)

原文鏈接:http://www.reibang.com/p/d544cd964ced

著作權(quán)歸作者所有,轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)易稠,并標注“簡書作者”包蓝。

下面舉幾個例子:

1、聲明delegate為strong類型测萎,簡而言之,如果父VC持有子VC份乒,并設置子VC的delegate為self(也就是父VC)腕唧,這樣的結(jié)果就是子VC也間接持有了父VC,造成循環(huán)引用枣接,在Pop子VC的時候不會調(diào)用delloc月腋。

2、timer是否持有self榆骚,我們一般要執(zhí)行一個timer的時候會用(NSTimer*)scheduledTimerWithTimeInterval:(NSTimeInterval)ti? target:(id)aTarget?selector:(SEL)aSelector? userInfo:(id)userInfo? repeats:(BOOL)yesOrNo這里的aTarget一般是self,這時候就需要注意了捌省,如果在你退出的時候這個timer還在執(zhí)行的話由于這個timer會持有self碉钠,所以delloc也不會調(diào)用卷拘,這里可以用weakSelf代替self也是沒有問題的祝高。

3、最常見的就是block導致的循環(huán)引用乍赫,由于在重構(gòu)APP中用到了MVVM架構(gòu)陆蟆,使用了大量的信號機制,導致block到處飛(哈哈)改鲫,解決的最多的就是這種了林束,解決方法也很簡單,就是在block外聲明__weaktype(self) weakSelf =self讲弄,在block中用weakSelf就可以了依痊,還有就是在block中如果使用了成員變量的下劃線形式也要改成weakSelf.PropertyName的形式怎披。MVVM中定義了宏對@weakify(self)和@strongify(self)可以理解為__weaktype(self) weakSelf = self的簡化形式,可以拿來直接使用性宏。

4状飞、圖片沒釋放,instrument調(diào)試后酵使,發(fā)現(xiàn)沒被釋放的全是imageIO焙糟,差不多就知道了,把讀圖的方式穿撮,從[UIImageimageNamed:@""],改成imageWithContentsOfFile痪欲,就可以了攻礼。

5礁扮、使用GPUImage處理拍照的時候,內(nèi)存穩(wěn)定不明增長深员。是Xcode7.1的問題。遮糖。只在debug的時候?qū)е聝?nèi)存崩潰叠赐,release的時候并不會造成內(nèi)存溢出,所以可以不必管它芭概。

6罢洲、CoreFoundation對象(C對象) : 只要函數(shù)中包含了create\new\copy\retain等關(guān)鍵字, 那么這些方法產(chǎn)生的對象,就必須在不再使用的時候調(diào)用1次CFRelease或者其他release函數(shù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市殿较,隨后出現(xiàn)的幾起案子桩蓉,更是在濱河造成了極大的恐慌,老刑警劉巖院究,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件业汰,死亡現(xiàn)場離奇詭異,居然都是意外死亡对供,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門鹅髓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來京景,“玉大人,你說我怎么就攤上這事醒串”苫剩” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵缠沈,是天一觀的道長错蝴。 經(jīng)常有香客問我,道長顷锰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任肛宋,我火速辦了婚禮悼吱,結(jié)果婚禮上慎框,老公的妹妹穿的比我還像新娘。我一直安慰自己薪丁,他們只是感情好馅精,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布洲敢。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪渗常。 梳的紋絲不亂的頭發(fā)上汗盘,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機與錄音癌椿,去河邊找鬼菱阵。 笑死,一個胖子當著我的面吹牛晴及,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播脆丁,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼动雹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了歼培?” 一聲冷哼從身側(cè)響起茸塞,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤钾虐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后效扫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡浩习,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年谱秽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疟赊。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡听绳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出头岔,到底是詐尸還是另有隱情,我是刑警寧澤峡竣,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布适掰,位于F島的核電站荠列,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏肌似。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一力细、第九天 我趴在偏房一處隱蔽的房頂上張望固额。 院中可真熱鬧,春花似錦逝慧、人聲如沸瑟捣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碱鳞。三九已至,卻和暖如春贵白,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背禁荒。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工呛伴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人热康。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓姐军,卻偏偏與公主長得像,于是被迫代替她去往敵國和親奕锌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344

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

  • 內(nèi)存管理 簡述OC中內(nèi)存管理機制固惯。與retain配對使用的方法是dealloc還是release缴守,為什么?需要與a...
    丶逐漸閱讀 1,948評論 1 16
  • 37.cocoa內(nèi)存管理規(guī)則 1)當你使用new贴捡,alloc或copy方法創(chuàng)建一個對象時村砂,該對象的保留計數(shù)器值為1...
    如風家的秘密閱讀 829評論 0 4
  • iOS內(nèi)存管理 概述 什么是內(nèi)存管理 應用程序內(nèi)存管理是在程序運行時分配內(nèi)存(比如創(chuàng)建一個對象,會增加內(nèi)存占用)與...
    蚊香醬閱讀 5,694評論 8 119
  • __block和__weak修飾符的區(qū)別其實是挺明顯的:1.__block不管是ARC還是MRC模式下都可以使用础废,...
    LZM輪回閱讀 3,284評論 0 6
  • iOS內(nèi)存管理機制的原理是引用計數(shù)评腺,引用計數(shù)簡單來說就是統(tǒng)計一塊內(nèi)存的所有權(quán),當這塊內(nèi)存被創(chuàng)建出來的時候蒿讥,它的引用...
    且行且珍惜_iOS閱讀 5,229評論 19 133