OC的內(nèi)存管理篇1---MRC

OC的內(nèi)存管理

開始之前, 先思考一個(gè)問(wèn)題:為什么要管理內(nèi)存?

曾看到一個(gè)笑話, 一個(gè)程序員去面試iOS程序員,面試官問(wèn):iOS開發(fā)中為什么需要內(nèi)存管理?
程序員淡定地說(shuō):內(nèi)存有限,所以要管理內(nèi)存啊.

答案很出乎意料,但是仔細(xì)想想,真是一語(yǔ)道破了本質(zhì).
那在內(nèi)存有限的情況下, 為什么要管理內(nèi)存呢?
在iOS開發(fā)中, 我們要保證有限的內(nèi)存資源得到最大化的利用,當(dāng)我們創(chuàng)建一個(gè)類的對(duì)象時(shí), 對(duì)應(yīng)的在內(nèi)存中,就得到一個(gè)塊內(nèi)存來(lái)存放這個(gè)對(duì)象的內(nèi)容. 但是這個(gè)對(duì)象(或者理解成一塊內(nèi)存), 可能被多個(gè)指針變量使用. 不要奇怪, 怎么又出現(xiàn)了指針變量. 這是因?yàn)?在objective-C中,我們都是通過(guò)對(duì)象的引用來(lái)操縱內(nèi)存的. 它本質(zhì)就是一個(gè)指針(該對(duì)象在內(nèi)存中的地址). 這樣做的好處是快呀. 試想, 我們?cè)陂_發(fā)中, 同一個(gè)對(duì)象可能被次使用, 如果直接操作對(duì)象本身,那么當(dāng)我們把一個(gè)對(duì)象賦值給另一個(gè)對(duì)象的時(shí)候,就需要把該對(duì)象中的所有內(nèi)容全部都挨個(gè)從該對(duì)象所在的內(nèi)存中取出來(lái),放到另外一塊內(nèi)存中. 如果,我們使用一個(gè)對(duì)象的地址來(lái)使用對(duì)象,那么就僅僅把一個(gè)整形值賦值給另外一個(gè)對(duì)象的引用就OK了.

  • 說(shuō)了那么多,看一下內(nèi)存的布局:


    可執(zhí)行文件在內(nèi)存中的布局

現(xiàn)在我們知道內(nèi)存管理實(shí)際上是管理我們的對(duì)象,對(duì)于其他的非對(duì)象類型不需要內(nèi)存管理(int,float,,,)
這是為什么呢?
這是因?yàn)?堆區(qū)需要程序員手動(dòng)管理, 棧區(qū)內(nèi)存由系統(tǒng)負(fù)責(zé)管理(申請(qǐng)和釋放).實(shí)際上,非對(duì)象類型的數(shù)據(jù)內(nèi)容和對(duì)象類型的數(shù)據(jù)內(nèi)容,一個(gè)放在棧里面,一個(gè)放在堆里面(這里暫時(shí)這么理解:其實(shí)和變量是否靜態(tài)以及是否是全局有關(guān)系), 本質(zhì)上我們管理內(nèi)存就是管理堆. 即便后來(lái)objective-C退出的ARC機(jī)制,也僅僅是為每個(gè)對(duì)象添加一個(gè)自己的引用計(jì)數(shù)器.(作用是記錄有多少"人"在使用它,或者說(shuō)有多少指針在指向這塊內(nèi)存),當(dāng)我們創(chuàng)建對(duì)象,對(duì)象之間相互傳值的時(shí)候, 系統(tǒng)自動(dòng)的加減引用計(jì)數(shù)的值代替程序員手動(dòng)的管理內(nèi)存.
注意:有些時(shí)候, 文中所指的對(duì)象和對(duì)象引用(指針)為同一概念, 但是對(duì)象的本質(zhì)是對(duì)應(yīng)堆區(qū)中的一塊內(nèi)存這一點(diǎn)是不變的

回到主題:為什么要管理內(nèi)存呢?不好回答. 我們可以取反唄, 如果不管理內(nèi)存會(huì)怎么樣?

  1. 如果內(nèi)存不管理, 那么手機(jī)中的內(nèi)存資源將會(huì)被很快的用完.
  2. 如果內(nèi)存得不到很好的管理, 可能會(huì)出現(xiàn)正在使用的對(duì)象,但是該對(duì)象所對(duì)應(yīng)的內(nèi)存已經(jīng)被系統(tǒng)釋放,甚至已被分配給別的對(duì)象. 造成野指針,甚至數(shù)據(jù)錯(cuò)誤的現(xiàn)象.
  3. 如果內(nèi)存得不到很好的管理,可能會(huì)出現(xiàn). 對(duì)象已經(jīng)沒有被使用了,但還沒有被釋放. 浪費(fèi)內(nèi)存.
  4. 如果內(nèi)存得不到很好的管理,還會(huì)出現(xiàn)很多問(wèn)題...

既然要管理內(nèi)存,就是要避免出現(xiàn)以上情況

如何管理內(nèi)存

objective-C中通過(guò)引用一個(gè)叫做引用計(jì)數(shù)器的機(jī)制,來(lái)管理內(nèi)存. 它的作用就是記錄當(dāng)前對(duì)象(一塊內(nèi)存)在程序中,有多少"人"在使用它.或者說(shuō)有多少指針正在指向它.如果,仍然有指針在指向這塊內(nèi)存,而此時(shí)我們卻釋放了這塊內(nèi)存,這時(shí)候,該指針就成野指針了.
管理內(nèi)存需要遵循的一些原則:

  1. 自己生成的對(duì)象自己持有
  2. 非自己生成的對(duì)象自己也能持有
  3. 不在需要自己持有的對(duì)象時(shí)釋放
  4. 非自己持有的對(duì)象不能釋放

在objective-C中都提供一些,供我們持有和釋放以及銷毀內(nèi)存的方法供程序員使用,以便需要的時(shí)候,調(diào)用對(duì)應(yīng)的方法來(lái)恰當(dāng)?shù)墓芾韮?nèi)存.

- (instancetype)retain OBJC_ARC_UNAVAILABLE;
- (oneway void)release OBJC_ARC_UNAVAILABLE;
- (instancetype)autorelease OBJC_ARC_UNAVAILABLE;
- (NSUInteger)retainCount OBJC_ARC_UNAVAILABLE;

+ (instancetype)alloc OBJC_SWIFT_UNAVAILABLE("use object initializers instead");
- (void)dealloc OBJC_SWIFT_UNAVAILABLE("use 'deinit' to define a de-initializer");

分別對(duì)應(yīng)下面的內(nèi)存管理動(dòng)作:

  1. 生成并持有 alloc ,new, copy等方法
  2. 持有 retain
  3. 釋放 release
  4. 銷毀 dealloc

在OC中通過(guò)alloc類方法,可以生成一個(gè)對(duì)象.也可以通過(guò)使用Copy,mutableCopy 來(lái)生成一個(gè)對(duì)象的副本. 返回一個(gè)指向這個(gè)對(duì)象的指針 , 這個(gè)對(duì)象是保存在內(nèi)存中的堆區(qū)的, 可以通過(guò)一個(gè)相同類型的指針變量來(lái)接收這個(gè)指針,從而使用它.但是這個(gè)指針變量是存儲(chǔ)在棧區(qū)的. 不需要管理, 系統(tǒng)會(huì)在"必要的時(shí)刻" 彈出棧幀, 這個(gè)時(shí)候,這個(gè)指針變量所指向的內(nèi)存會(huì)release.

生成并持有的使用場(chǎng)景:


引用計(jì)數(shù)

到了總結(jié)的時(shí)候了:也就是說(shuō),objective-C中的內(nèi)存管理,管理的是內(nèi)存中堆區(qū)中存放的對(duì)象,通過(guò)為每個(gè)對(duì)象增添一個(gè)引用計(jì)數(shù)器來(lái)實(shí)現(xiàn), 我們需要根據(jù)代碼中有多少引用指向該對(duì)象來(lái)動(dòng)態(tài)的增加(向?qū)ο蟀l(fā)送retain消息)和減少(向?qū)ο蟀l(fā)送release消息)引用計(jì)數(shù)器的值.

對(duì)于上文中所提到的內(nèi)存管理需要遵循的原則沒有詳細(xì)說(shuō)明:打算下一篇在ARC中說(shuō)明.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • iOS內(nèi)存管理 概述 什么是內(nèi)存管理 應(yīng)用程序內(nèi)存管理是在程序運(yùn)行時(shí)分配內(nèi)存(比如創(chuàng)建一個(gè)對(duì)象,會(huì)增加內(nèi)存占用)與...
    蚊香醬閱讀 5,823評(píng)論 8 119
  • ARC在OC里面?zhèn)€人感覺又是一個(gè)高大上的牛詞,在前面Objective-C中的內(nèi)存管理部分提到了ARC內(nèi)存管理機(jī)制...
    skylor閱讀 858評(píng)論 0 2
  • 29.理解引用計(jì)數(shù) Objective-C語(yǔ)言使用引用計(jì)數(shù)來(lái)管理內(nèi)存,也就是說(shuō),每個(gè)對(duì)象都有個(gè)可以遞增或遞減的計(jì)數(shù)...
    Code_Ninja閱讀 1,743評(píng)論 1 3
  • 18年剛開年不久,為了避免自己陷入只是低頭猛跑,卻忘記看路的毛病,年初這個(gè)時(shí)間點(diǎn)上對(duì)自己現(xiàn)階段認(rèn)為的“剛需”做...
    TIF_eba6閱讀 222評(píng)論 1 0
  • 孩子發(fā)皮、不聽話、不好好吃飯、不認(rèn)真寫作業(yè),這些不良的行為總是困擾著做家長(zhǎng)的我們。自己有時(shí)候總是控制不住對(duì)孩子的暴...
    6_myr閱讀 1,007評(píng)論 0 0

友情鏈接更多精彩內(nèi)容