iOS内存管理(ARC,MRC)
iOS內(nèi)存管理方式:
?
ARC Automatic Reference Counting 自動(dòng)引用計(jì)數(shù)
MRC Manual Reference Counting 手動(dòng)引用計(jì)數(shù)
?
更改管理方式:
?
?
?
內(nèi)存管理的問題:
?
1、內(nèi)存泄露:不再需要的對(duì)象沒有釋放。
2、野指針:正在使用的對(duì)象提前釋放。
?
引用計(jì)數(shù):
?
1、每一個(gè)對(duì)象上都有一個(gè)引用計(jì)數(shù)器
2、當(dāng)對(duì)象出生時(shí)引用計(jì)數(shù)器為1
3、當(dāng)對(duì)象調(diào)用retain方法時(shí)引用計(jì)數(shù)器+1
4、當(dāng)對(duì)象調(diào)用release方法時(shí)引用計(jì)數(shù)器-1
5、當(dāng)一個(gè)對(duì)象引用計(jì)數(shù)為0時(shí),這個(gè)對(duì)象立即被回收
?
僵尸對(duì)象:過度釋放的對(duì)象。
?
iOS為了優(yōu)化app性能,不會(huì)馬上處理僵尸對(duì)象,如圖所示可以開啟僵尸模式。
?
?
dealloc 方法:
?
當(dāng)對(duì)象的retainCount=0時(shí)自動(dòng)調(diào)用。
dealloc里release成員變量對(duì)象。
dealloc必須調(diào)用父類方法,[super dealloc]必須放在最后。
dealloc由系統(tǒng)自動(dòng)調(diào)用,不能手動(dòng)調(diào)用。
dealloc的優(yōu)化 self.dog = nil;
?
內(nèi)存管理原則:
?
誰(shuí)申請(qǐng),誰(shuí)釋放。
申請(qǐng)的方法:alloc new? copy mutableCopy retain
釋放的方法:release
?
@property修飾詞補(bǔ)充:
?
1、默認(rèn)assign
2、assign 主要修飾基本數(shù)據(jù)類型 int long float double 不添加任何管理內(nèi)存的代碼
3、retain 主要修飾OC對(duì)象 添加管理內(nèi)存的代碼
?
Autorelease自動(dòng)釋放池
?
(一)基本用法
(1)會(huì)將對(duì)象放到一個(gè)自動(dòng)釋放池中
(2)當(dāng)自動(dòng)釋放池被銷毀時(shí),會(huì)對(duì)池子里的所有對(duì)象做一次release
(3)會(huì)返回對(duì)象本身
(4)調(diào)用完autorelease方法后,對(duì)象的計(jì)數(shù)器不受影響(銷毀時(shí)影響)
(二)好處
(1)不需要再關(guān)心對(duì)象釋放的時(shí)間
(2)不需要再關(guān)心什么時(shí)候調(diào)用release
(三)使用注意
(1)占用內(nèi)存較大的對(duì)象,不要隨便使用autorelease,應(yīng)該使用release來精確控制
(2)占用內(nèi)存較小的對(duì)象使用autorelease,沒有太大的影響
(四)錯(cuò)誤寫法
(1)連續(xù)調(diào)用多次autorelease,釋放池銷毀時(shí)執(zhí)行兩次release(-1嗎?)
(2)Alloc之后調(diào)用了autorelease,之后又調(diào)用了release。
(五)自動(dòng)釋放池
(1)在ios程序運(yùn)行過程中,會(huì)創(chuàng)建無數(shù)個(gè)池子,這些池子都是以棧結(jié)構(gòu)(先進(jìn)后出)存在的。
(2)當(dāng)一個(gè)對(duì)象調(diào)用autorelease時(shí),會(huì)將這個(gè)對(duì)象放到位于棧頂?shù)尼尫懦刂?/p>
(六)自動(dòng)釋放池的創(chuàng)建方式
(1)ios 5.0以前的創(chuàng)建方式
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
`````````````````
[pool release];//[pool drain];用于mac
(2)Ios5.0以后
@autoreleasepool
{//開始代表創(chuàng)建自動(dòng)釋放池
·······
}//結(jié)束代表銷毀自動(dòng)釋放池
(七)Autorelease注意
(1)系統(tǒng)自帶的方法中,如果不包含alloc new copy等,則這些方法返回的對(duì)象都是autorelease的,如[NSDate date];
(2)開發(fā)中經(jīng)常會(huì)寫一些類方法來快速創(chuàng)建一個(gè)autorelease對(duì)象,創(chuàng)建對(duì)象時(shí)不要直接使用類名,而是使用self
?
?
ARC內(nèi)存管理機(jī)制
?
(一)ARC的判斷準(zhǔn)則:
只要沒有強(qiáng)指針指向?qū)ο?#xff0c;對(duì)象就會(huì)被釋放。
(二)指針分類:
(1)強(qiáng)指針:默認(rèn)的情況下,所有的指針都是強(qiáng)指針,關(guān)鍵字__strong
(2)弱指針:_ _weak關(guān)鍵字修飾的指針
聲明一個(gè)弱指針如下:
__weak Person *p;
ARC中,只要弱指針指向的對(duì)象不在了,就直接把弱指針做清空操作。
__weak Person *p=[[Person alloc] init];//不合理,對(duì)象一創(chuàng)建出來就被釋放掉,對(duì)象釋放掉后,ARC把指針自動(dòng)清零。
ARC中在property處不再使用retain,而是使用strong,在dealloc中不需要再[super dealloc]。
@property(nonatomic,strong)Dog *dog;// 意味著生成的成員變量_dog是一個(gè)強(qiáng)指針,相當(dāng)于以前的retain。
如果換成是弱指針,則換成weak,不需要加__。
?
(三)ARC的特點(diǎn)總結(jié):
(1)不允許調(diào)用release,retain,retainCount
(2)允許重寫dealloc,但是不允許調(diào)用[super dealloc]
(3)@property的參數(shù):
Strong:相當(dāng)于原來的retain(適用于OC對(duì)象類型),成員變量是強(qiáng)指針
Weak:相當(dāng)于原來的assign,(適用于oc對(duì)象類型),成員變量是弱指針
Assign:適用于非OC對(duì)象類型(基礎(chǔ)類型)
?
?
MRC環(huán)境get方法實(shí)現(xiàn):
?
//atomic下get方法
- (Keyborad *)kb {
?? ?
? ? [_kb retain];
? ? [_kb autorelease];
?? ?
? ? return _kb;
}
?
//nonatomic下get方法
- (Keyborad *)kb {
?? ?
? ? return _kb;
}
?
MRC轉(zhuǎn)ARC:
?
?
MRC與ARC混編:
?
ARCMRC
在的選項(xiàng)下下選擇要不使用編譯的文件,雙擊它,輸入-fno-objc-arc即可
?
MRC工程中也可以使用ARC的類。
在的選項(xiàng)下下選擇要使用編譯的文件,雙擊它,輸入即可
?
循環(huán)引用:A對(duì)象強(qiáng)指針引用了B對(duì)象,B對(duì)象強(qiáng)指針引用了A對(duì)象,彼此引用無法銷毀。
?
解決方法:將其中的一條強(qiáng)指針改成用weak修飾的弱指針。
?
轉(zhuǎn)載于:https://www.cnblogs.com/dxb123456/p/5487706.html
總結(jié)
以上是生活随笔為你收集整理的iOS内存管理(ARC,MRC)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深度学习04-RNN
- 下一篇: 再谈BERT