iOS內(nèi)存管理淺談

流程圖如下

WechatIMG4976.jpeg

上面是我針對內(nèi)存管理的了解撩银,進(jìn)行了一個(gè)簡單的用流程的方式加以概括给涕。下面是詳細(xì)的說明一下,在面試過程中额获,針對內(nèi)存管理够庙,面試官經(jīng)常會問到哪些問題進(jìn)行剖析。

之前面試的時(shí)候抄邀,面試官都會問的問題是耘眨,你對內(nèi)存管理了解嗎?簡單說一下境肾,而我就會將上面這個(gè)圖設(shè)計(jì)到的點(diǎn)全都用手繪的形式給他講一遍剔难。這樣你就占據(jù)了主導(dǎo)位置。哈哈哈

內(nèi)存管理分為 mrc和arc兩種管理方式奥喻。
我們先從mrc說起偶宫。

MRC

規(guī)則:誰創(chuàng)建,誰釋放环鲤,誰引用纯趋,誰管理的原則。
alloc, init,new,copy-------->release
當(dāng)一個(gè)對象的retainCount = 0的時(shí)候冷离,就會調(diào)用dealloc方式吵冒,將對象釋放掉。釋放內(nèi)存的并不是release酒朵,而是dealloc桦锄。

retain是保持的意思,給一個(gè)對象發(fā)送retian消息,就意味著保持這個(gè)對象蔫耽。它的retainCount+1结耀。具體我用一張流程圖說明:


屏幕快照 2019-04-02 上午9.54.19.png

針對上面這些內(nèi)容留夜,其實(shí)可以引申出很多面試題。舉個(gè)例子??:

什么情況下使用weak關(guān)鍵字图甜,相比assgin有什么不同碍粥?

1、delegate.因?yàn)樵赼rc中黑毅,有可能會出現(xiàn)循環(huán)引用嚼摩。
2、自身已經(jīng)對它進(jìn)行一次強(qiáng)引用矿瘦,沒有必要再強(qiáng)引用一次枕面,比如IBOutlet控件屬性。

不同點(diǎn)
1缚去、weak為屬性設(shè)置新值的時(shí)候潮秘,設(shè)置方法既不保留新值,也不釋放舊值易结。在遭到摧毀時(shí)枕荞,屬性值也會被清空。assgin的設(shè)置方法只針對基本數(shù)據(jù)類型等簡單的賦值操作搞动。
2躏精、assgin可以用非OC對象,weak必須用于oc對象鹦肿。

runtime如何實(shí)現(xiàn)weak屬性矗烛、實(shí)現(xiàn)原理

這個(gè)會在后續(xù)的篇幅中重點(diǎn)介紹

@property中有哪些屬性關(guān)鍵字?/@property后面可以有哪些修飾符狮惜?
屏幕快照 2019-04-02 上午10.35.51.png

或者換一個(gè)問法:

屬性readwrite高诺,readonly,assign碾篡,retain虱而,copy,nonatomic 各是什么作用开泽,在那種情況下用?

1). readwrite 是可讀可寫特性;需要生成getter方法和setter方法時(shí)
2). readonly 是只讀特性 只會生成getter方法 不會生成setter方法 ;不希望屬性在類外改變
3). assign 是賦值特性牡拇,setter方法將傳入?yún)?shù)賦值給實(shí)例變量;僅設(shè)置變量時(shí);
4). retain 表示持有特性,setter方法將傳入?yún)?shù)先保留穆律,再賦值惠呼,傳入?yún)?shù)的retaincount會+1;
5). copy 表示賦值特性,setter方法將傳入對象復(fù)制一份;需要完全一份新的變量時(shí)峦耘。
6).nonatomic 非原子操作剔蹋,決定編譯器生成的setter getter是否是原子操作,atomic表示多線程安全辅髓,一般使用nonatomic

weak屬性在dealloc中置nil么泣崩?

不需要少梁。
在ARC中環(huán)境無論是強(qiáng)指針還是弱指針都無需在dealloc設(shè)置為Nil,ARC會自動幫我們處理。
在屬性所指的對象遭到摧毀時(shí)矫付,屬性值也會清空凯沪。

- (void)setObject:(NSObject *)object{
    objc_setAssociatedObject(self, @"object", object, OBJC_ASSOCIATION_ASSIGN);
    [object cyl_runAtDealloc:^{
        _object = nil;
    }];
}

關(guān)于copy關(guān)鍵字的深淺拷貝等面試題,會在后面提到买优。我們繼續(xù)說一下內(nèi)存管理妨马。

ARC

還是上面那張關(guān)于引用計(jì)數(shù)的流程圖。

autorelease

實(shí)現(xiàn)杀赢、本質(zhì)烘跺、RunLoop相關(guān)

·App啟動后,蘋果在主線程 RunLoop 里注冊了兩個(gè) Observer葵陵,其回調(diào)都是 _wrapRunLoopWithAutoreleasePoolHandler()液荸。
·第一個(gè) Observer 監(jiān)視的事件是 Entry(即將進(jìn)入Loop),其回調(diào)內(nèi)會調(diào)用 _objc_autoreleasePoolPush() 創(chuàng)建自動釋放池脱篙。其 order 是-2147483647,優(yōu)先級最高伤柄,保證創(chuàng)建釋放池發(fā)生在其他所有回調(diào)之前绊困。
·第二個(gè) Observer 監(jiān)視了兩個(gè)事件: BeforeWaiting(準(zhǔn)備進(jìn)入休眠) 時(shí)調(diào)用_objc_autoreleasePoolPop() 和 _objc_autoreleasePoolPush() 釋放舊的池并創(chuàng)建新池;Exit(即將退出Loop) 時(shí)調(diào)用 _objc_autoreleasePoolPop() 來釋放自動釋放池适刀。這個(gè) Observer 的 order 是 2147483647秤朗,優(yōu)先級最低,保證其釋放池子發(fā)生在其他所有回調(diào)之后笔喉。
·在主線程執(zhí)行的代碼取视,通常是寫在諸如事件回調(diào)、Timer回調(diào)內(nèi)的常挚。這些回調(diào)會被 RunLoop 創(chuàng)建好的 AutoreleasePool 環(huán)繞著作谭,所以不會出現(xiàn)內(nèi)存泄漏,開發(fā)者也不必顯示創(chuàng)建 Pool 了奄毡。

也就是說AutoreleasePool創(chuàng)建是在一個(gè)RunLoop事件開始之前(push)折欠,AutoreleasePool釋放是在一個(gè)RunLoop事件即將結(jié)束之前(pop)。
AutoreleasePool里的Autorelease對象的加入是在RunLoop事件中吼过,AutoreleasePool里的Autorelease對象的釋放是在AutoreleasePool釋放時(shí)锐秦。

具體見這篇文章,非常清楚
AutoreleasePool底層實(shí)現(xiàn)原理剖析

問:
1盗忱、談?wù)勀銓ψ詣俞尫懦氐睦斫?br> 2酱床、多層自動釋放池嵌套的對象在哪一層釋放。

自動釋放池是oc提供的一種自動回收的機(jī)制趟佃,具有延遲釋放的特性扇谣,即當(dāng)我們創(chuàng)建了一個(gè)對象慷垮,并把他加入到了自動釋放池中時(shí),他不會立即被釋放揍堕,會等到一次runloop結(jié)束或者作用域超出{}或者超出[pool release]之后再被釋放料身。

Objective-C如何對內(nèi)存管理的,說說你的看法和解決方法?

答:Objective-C的內(nèi)存管理主要有三種方式ARC(自動內(nèi)存計(jì)數(shù))、手動內(nèi)存計(jì)數(shù)衩茸、內(nèi)存池芹血。
1). (Garbage Collection)自動內(nèi)存計(jì)數(shù):這種方式和java類似,在你的程序的執(zhí)行過程中楞慈。始終有一個(gè)高人在背后準(zhǔn)確地幫你收拾垃圾幔烛,你不用考慮它什么時(shí)候開始工作,怎樣工作囊蓝。你只需要明白饿悬,我申請了一段內(nèi)存空間,當(dāng)我不再使用從而這段內(nèi)存成為垃圾的時(shí)候聚霜,我就徹底的把它忘記掉狡恬,反正那個(gè)高人會幫我收拾垃圾。遺憾的是蝎宇,那個(gè)高人需要消耗一定的資源弟劲,在攜帶設(shè)備里面,資源是緊俏商品所以iPhone不支持這個(gè)功能姥芥。所以“Garbage Collection”不是本入門指南的范圍兔乞,對“Garbage Collection”內(nèi)部機(jī)制感興趣的同學(xué)可以參考一些其他的資料,不過說老實(shí)話“Garbage Collection”不大適合適初學(xué)者研究凉唐。
解決方法: 通過alloc – initial方式創(chuàng)建的, 創(chuàng)建后引用計(jì)數(shù)+1, 此后每retain一次引用計(jì)數(shù)+1, 那么在程序中做相應(yīng)次數(shù)的release就好了.
2). (Reference Counted)手動內(nèi)存計(jì)數(shù):就是說庸追,從一段內(nèi)存被申請之后,就存在一個(gè)變量用于保存這段內(nèi)存被使用的次數(shù)台囱,我們暫時(shí)把它稱為計(jì)數(shù)器淡溯,當(dāng)計(jì)數(shù)器變?yōu)?的時(shí)候,那么就是釋放這段內(nèi)存的時(shí)候玄坦。比如說血筑,當(dāng)在程序A里面一段內(nèi)存被成功申請完成之后,那么這個(gè)計(jì)數(shù)器就從0變成1(我們把這個(gè)過程叫做alloc)煎楣,然后程序B也需要使用這個(gè)內(nèi)存豺总,那么計(jì)數(shù)器就從1變成了2(我們把這個(gè)過程叫做retain)。緊接著程序A不再需要這段內(nèi)存了择懂,那么程序A就把這個(gè)計(jì)數(shù)器減1(我們把這個(gè)過程叫做release);程序B也不再需要這段內(nèi)存的時(shí)候喻喳,那么也把計(jì)數(shù)器減1(這個(gè)過程還是release)。當(dāng)系統(tǒng)(也就是Foundation)發(fā)現(xiàn)這個(gè)計(jì)數(shù)器變 成員了0困曙,那么就會調(diào)用內(nèi)存回收程序把這段內(nèi)存回收(我們把這個(gè)過程叫做dealloc)表伦。順便提一句谦去,如果沒有Foundation,那么維護(hù)計(jì)數(shù)器蹦哼,釋放內(nèi)存等等工作需要你手工來完成鳄哭。
解決:一般是由類的靜態(tài)方法創(chuàng)建的, 函數(shù)名中不會出現(xiàn)alloc或init字樣, 如[NSString string]和[NSArray arrayWithObject:], 創(chuàng)建后引用計(jì)數(shù)+0, 在函數(shù)出棧后釋放, 即相當(dāng)于一個(gè)棧上的局部變量. 當(dāng)然也可以通過retain延長對象的生存期.
3). (NSAutoRealeasePool)內(nèi)存池:可以通過創(chuàng)建和釋放內(nèi)存池控制內(nèi)存申請和回收的時(shí)機(jī).
解決:是由autorelease加入系統(tǒng)內(nèi)存池, 內(nèi)存池是可以嵌套的, 每個(gè)內(nèi)存池都需要有一個(gè)創(chuàng)建釋放對, 就像main函數(shù)中寫的一樣. 使用也很簡單, 比如[[[NSString alloc]initialWithFormat:@”Hey you!”] autorelease], 即將一個(gè)NSString對象加入到最內(nèi)層的系統(tǒng)內(nèi)存池, 當(dāng)我們釋放這個(gè)內(nèi)存池時(shí), 其中的對象都會被釋放.

內(nèi)存管理的幾條原則時(shí)什么?按照默認(rèn)法則.那些關(guān)鍵字生成的對象需要手動釋放?在和property結(jié)合的時(shí)候怎樣有效的避免內(nèi)存泄露?

答:誰申請,誰釋放

遵循Cocoa Touch的使用原則;

內(nèi)存管理主要要避免“過早釋放”和“內(nèi)存泄漏”纲熏,對于“過早釋放”需要注意@property設(shè)置特性時(shí)妆丘,一定要用對特性關(guān)鍵字,對于“內(nèi)存泄漏”局劲,一定要申請了要負(fù)責(zé)釋放勺拣,要細(xì)心。

關(guān)鍵字alloc 或new 生成的對象需要手動釋放;

設(shè)置正確的property屬性鱼填,對于retain需要在合適的地方釋放药有,
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市苹丸,隨后出現(xiàn)的幾起案子愤惰,更是在濱河造成了極大的恐慌,老刑警劉巖谈跛,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件羊苟,死亡現(xiàn)場離奇詭異,居然都是意外死亡感憾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門令花,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阻桅,“玉大人,你說我怎么就攤上這事兼都∩┏粒” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵扮碧,是天一觀的道長趟章。 經(jīng)常有香客問我,道長慎王,這世上最難降的妖魔是什么蚓土? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任供嚎,我火速辦了婚禮砂蔽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘老虫。我一直安慰自己咱旱,他們只是感情好确丢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布绷耍。 她就那樣靜靜地躺著,像睡著了一般鲜侥。 火紅的嫁衣襯著肌膚如雪褂始。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天描函,我揣著相機(jī)與錄音崎苗,去河邊找鬼。 笑死赘阀,一個(gè)胖子當(dāng)著我的面吹牛益缠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播基公,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼幅慌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了轰豆?” 一聲冷哼從身側(cè)響起胰伍,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎酸休,沒想到半個(gè)月后骂租,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡斑司,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年渗饮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宿刮。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡互站,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出僵缺,到底是詐尸還是另有隱情胡桃,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布磕潮,位于F島的核電站翠胰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏自脯。R本人自食惡果不足惜之景,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冤今。 院中可真熱鬧闺兢,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至桐磁,卻和暖如春悔耘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背我擂。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工衬以, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人校摩。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓看峻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親衙吩。 傳聞我的和親對象是個(gè)殘疾皇子互妓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

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

  • 內(nèi)存管理 簡述OC中內(nèi)存管理機(jī)制。與retain配對使用的方法是dealloc還是release坤塞,為什么冯勉?需要與a...
    丶逐漸閱讀 1,964評論 1 16
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,103評論 1 32
  • 內(nèi)存管理ARC處理原理ARC是Objective-C編譯器的特性,而不是運(yùn)行時(shí)特性或者垃圾回收機(jī)制摹芙,ARC所做的只...
    陽明先生_X自主閱讀 336評論 0 3
  • 29.理解引用計(jì)數(shù) Objective-C語言使用引用計(jì)數(shù)來管理內(nèi)存灼狰,也就是說,每個(gè)對象都有個(gè)可以遞增或遞減的計(jì)數(shù)...
    Code_Ninja閱讀 1,490評論 1 3
  • 一、什么是受害者情緒 每個(gè)人面對生活都有不同的心態(tài)盈电,有積極樂觀的承绸,有消極被動的,其中有一種情緒受眾最為廣泛挣轨,就是“...
    可樂君CC閱讀 482評論 0 3