一個(gè)函數(shù)可以返回棧空間的數(shù)據(jù)毫目,但不能返回椫迓空間的地址
需要加if判斷并free呢撞,修改如下:
- retain:增加對(duì)象的引用計(jì)數(shù)
EXC:exception 異常
ACCESS:訪問(wèn)
EXC_BAD_ACCESS:使用了野指針,即空間已經(jīng)被釋放了条获,但任然使用該指針忠荞。
手動(dòng)內(nèi)存管理原則是:誰(shuí)創(chuàng)建誰(shuí)釋放,誰(shuí)加一誰(shuí)減一;
[pool drain]給自動(dòng)釋放池中的每一個(gè)對(duì)象發(fā)一個(gè)release消息委煤,池中的每個(gè)對(duì)象retainCount都減一
要把一個(gè)對(duì)象(比如dog)放入當(dāng)前環(huán)境中的自動(dòng)釋放池中有兩種方法:
CDDog *dog = [[[CDDog alloc] init]autorelease];
如果使用了自動(dòng)釋放池就不能再進(jìn)行release操作
ARC模式下要正確的使用內(nèi)存最關(guān)鍵的就是書寫正確的和內(nèi)存管理相關(guān)的屬性修飾符
- strong:對(duì)象指針一般都用strong 表示對(duì)引用計(jì)數(shù)加1堂油,strong是屬性修飾符的默認(rèn)值。除了讓指針指向給定的地址碧绞,還做了對(duì)象引用計(jì)數(shù)
- weak:如果對(duì)象出現(xiàn)循環(huán)引用的時(shí)候府框,必須用weak
- 1、出現(xiàn)循環(huán)引用時(shí)候讥邻,有一方必須使用weak迫靖,以破除循環(huán)引用
- 2、一個(gè)對(duì)象的生命周期不由你自己的代碼管理兴使,例如可視化編程系宜,要使用weak。
- 3发魄、如果屬性是一個(gè)協(xié)議指針也應(yīng)該使用weak
- copy:
- 1盹牧、確保NSString、NSArray励幼、NSDictionary汰寓、NSData等不可變類型指針是確確實(shí)實(shí)指向一個(gè)不可變對(duì)象
- 2、如果屬性是一個(gè)Block 類型的變量苹粟,必須用copy有滑。
- assign:
- 1、基本數(shù)據(jù)類型都用assign嵌削。包括:非對(duì)象指針類型(整形毛好、float、char掷贾、字符型、實(shí)型荣茫、布爾型想帅、枚舉、結(jié)構(gòu)體啡莉、聯(lián)合體)港准。
- 2、如果屬性是對(duì)象指針咧欣,assign相當(dāng)于weak浅缸。
不要再C的結(jié)構(gòu)體中使用對(duì)象指針,因?yàn)闊o(wú)法進(jìn)行內(nèi)存管理魄咕。
自動(dòng)釋放池是可以嵌套的
面試題
1衩椒、說(shuō)說(shuō)對(duì)內(nèi)存管理的理解??
- 手動(dòng)(MRC):
- 在創(chuàng)建一個(gè)對(duì)象時(shí)候毛萌,系統(tǒng)會(huì)自動(dòng)創(chuàng)建這個(gè)對(duì)象的引用計(jì)數(shù)苟弛,并且賦值位1;
- 當(dāng)引用計(jì)數(shù)為0的時(shí)候阁将,對(duì)象會(huì)去調(diào)用dealloc方法膏秫,以銷毀對(duì)象;
- 對(duì)象調(diào)用release方法會(huì)讓引用計(jì)數(shù)減一做盅,調(diào)用retain方法讓對(duì)象的引用計(jì)數(shù)加一
- 自動(dòng)(ARC):
- 在ARC中管理內(nèi)存的實(shí)質(zhì)還是通過(guò)引用計(jì)數(shù)去管理的缤削,但是程序員不再關(guān)心引用計(jì)數(shù)器的值。在ARC環(huán)境下吹榴,系統(tǒng)會(huì)在程序編譯的時(shí)候會(huì)自動(dòng)在合適的地方添加retain亭敢、release或者autorelease。
- 當(dāng)強(qiáng)指針指向的時(shí)候腊尚,對(duì)象不銷毀吨拗;弱指針不影響對(duì)象的銷毀;指針默認(rèn)都是強(qiáng)指針婿斥。(ARC中可以重寫dealloc方法劝篷,但絕對(duì)不可以調(diào)用父類的dealloc,在對(duì)象即將被銷毀是調(diào)用dealloc)民宿。
- _weak 使用這個(gè)關(guān)鍵字修飾的指針是弱指針娇妓;_strong 使用這個(gè)關(guān)鍵字的指針是強(qiáng)指針(默認(rèn)值)
2、手動(dòng)內(nèi)存管理的原則活鹰?
- 程序中如果出現(xiàn)alloc哈恰、retain、new志群、必須配對(duì)出現(xiàn)一個(gè)release或者autorelease着绷;誰(shuí)創(chuàng)建誰(shuí)釋放,誰(shuí)加一誰(shuí)減一锌云,在哪兒創(chuàng)建在哪兒釋放
3荠医、autoReleasePool的原理和autorelease的作用
- autoReleasePool原理:當(dāng)autoReleasePool銷毀時(shí),會(huì)將自動(dòng)釋放池中所有的對(duì)象一次release方法
- autorelease的作用:將對(duì)象放到自動(dòng)釋放池中(并不是寫在自動(dòng)釋放池的大括號(hào)中的對(duì)象就是自動(dòng)釋放池中的對(duì)象)桑涎。release是立刻將計(jì)數(shù)器減1彬向,autorelease的對(duì)象要等autoReleasePool銷毀時(shí)才會(huì)計(jì)數(shù)器減1,即會(huì)延時(shí)銷毀攻冷。也就是autorelease本身不能使計(jì)數(shù)器減1
4娃胆、MRC中符合內(nèi)存管理的set方法的書寫
- 舊值release哟冬、新值retain博投,然后賦值
5、屬性修飾符(strong哥艇、weak、copy招驴、assign篙程、retain)
- strong:控制@property實(shí)現(xiàn)符合內(nèi)存管理的set方法,引用計(jì)數(shù)加1别厘;修飾一般的對(duì)象虱饿。
- weak:控制@property實(shí)現(xiàn)一般的set方法(字節(jié)賦值),只能修飾對(duì)象触趴,用來(lái)避免循環(huán)引用
- copy:控制@property實(shí)現(xiàn)的set方法氮发,會(huì)先創(chuàng)建一個(gè)新的對(duì)象,然后將參數(shù)的值傳給新的對(duì)象冗懦,最后將新的對(duì)象賦給成員變量爽冕。常用來(lái)修飾字符串、數(shù)組披蕉、字典和block颈畸、NSData。
- assign:控制@property實(shí)現(xiàn)一般的set方法(字節(jié)賦值)没讲;常用來(lái)修飾基本數(shù)據(jù)類型int眯娱、float、char爬凑、結(jié)構(gòu)體徙缴、枚舉
- retain:在MRC中,相當(dāng)于strong嘁信,實(shí)現(xiàn)的set方法就是舊值release于样、新值retain
6、內(nèi)存管理的作用:解決內(nèi)存泄露和野指針操作
7潘靖、內(nèi)存管理的原理:分MRC和ARC
8穿剖、一個(gè)工程中只能有一個(gè)自動(dòng)釋放池嗎? 錯(cuò)卦溢,可以NSAutoreleasePool或@autoreleasepool{}去創(chuàng)建多個(gè)自動(dòng)釋放池糊余。
9、在手動(dòng)內(nèi)存管理中既绕,盡量都使用autorelease嗎啄刹?
- 錯(cuò)涮坐,對(duì)象調(diào)用autorelease會(huì)延時(shí)對(duì)象銷毀凄贩,如果所有的對(duì)象都延遲銷毀的話,就相當(dāng)于沒(méi)有做內(nèi)存管理
10袱讹、內(nèi)存分為幾大區(qū)域:
- 棧區(qū):存儲(chǔ)局部變量(包括指向?qū)ο蟮闹羔?疲扎。內(nèi)存分配時(shí)是按照地址從高到低分配的昵时。對(duì)于局部變量而言,如函數(shù)或者代碼塊結(jié)束時(shí)椒丧,系統(tǒng)會(huì)自動(dòng)回收空間壹甥,所以不需要程序員管理
- 堆區(qū):程序運(yùn)行過(guò)程中動(dòng)態(tài)分配的存儲(chǔ)空間,內(nèi)存分配時(shí)是按照地址從低到高分配的壶熏。這是需要程序員管理的那部分句柠,即程序員需要管理任何繼承NSObject的對(duì)象,而對(duì)其他的基本數(shù)據(jù)類型無(wú)效
- BSS段:沒(méi)有初始化的全局變量和靜態(tài)變量棒假。程序啟動(dòng)時(shí)溯职,自動(dòng)加載該空間,所以不需要程序員管理
- 數(shù)據(jù)區(qū):已經(jīng)初始化的全局變量和靜態(tài)變量帽哑、字符串常量谜酒。程序啟動(dòng)時(shí),自動(dòng)加載該空間妻枕,所以不需要程序員管理
- 代碼段:存儲(chǔ)編譯后的代碼僻族。程序啟動(dòng)時(shí),自動(dòng)加載該空間屡谐,所以不需要程序員管理
11述么、引用計(jì)數(shù)器的作用
- 引用計(jì)數(shù)器是判斷對(duì)象要不要回收的依據(jù)。但有一種例外:對(duì)象值為nil康嘉,引用計(jì)數(shù)為碉输,例如:person *p = nil;這個(gè)根本就沒(méi)有創(chuàng)建空間亭珍。retaincount可用%ld 敷钾、%tu來(lái)打印
12、dealloc相關(guān)
- ARC中可以重寫dealloc方法肄梨,但絕對(duì)不可以調(diào)用父類的dealloc阻荒,在對(duì)象即將被銷毀是調(diào)用dealloc.
- 在MRC中,當(dāng)對(duì)象被銷毀時(shí)众羡,系統(tǒng)會(huì)自動(dòng)向?qū)ο蟀l(fā)送一條dealloc消息(程序員可重寫dealloc方法)侨赡,在其中釋放相關(guān)資源,dealloc就像是對(duì)象的臨終遺言粱侣。一旦重寫了dealloc方法羊壹,就必須調(diào)用[super dealloc],并且放在代碼塊的最后調(diào)用齐婴,而不能直接調(diào)用油猫。
- 一旦對(duì)象被回收了,那么他所占據(jù)的存儲(chǔ)空間就不再可用柠偶,堅(jiān)持使用就會(huì)導(dǎo)致程序崩潰情妖,即野指針錯(cuò)誤