关于OC的内存管理-01
1.什么是內(nèi)存管理?
大家都知道手機(jī)的內(nèi)存是有限的,app應(yīng)用的內(nèi)存也應(yīng)該是受限制的,隨著app應(yīng)用的使用會(huì)導(dǎo)致內(nèi)存的占用率增大。當(dāng)內(nèi)存占用率達(dá)到一種程度時(shí)。系統(tǒng)會(huì)發(fā)出內(nèi)存警告。這時(shí)我們須要把一些不用的對象和變量所占用的內(nèi)存釋放掉,也就是說我們須要手動(dòng)對內(nèi)存進(jìn)行管理。
而我們管理的范圍:不論什么繼承了NSObject 的對象,對于基本數(shù)據(jù)類型(比方float、int 、char、struct、enum等)則是無效的。
2.怎樣進(jìn)行內(nèi)存管理
1)每一個(gè)OC對象本身就有一個(gè)占用4個(gè)字節(jié)內(nèi)存的計(jì)數(shù)器,它存儲(chǔ)的是一個(gè)整數(shù)。表示“當(dāng)前對象被引用的次數(shù)”。當(dāng)對象一被建立的時(shí)候(比如alloc、new、copy)就默覺得1。而計(jì)數(shù)器的作用就是,當(dāng)對象的計(jì)數(shù)器為0時(shí),當(dāng)前對象就會(huì)被系統(tǒng)回收,假設(shè)計(jì)數(shù)器不為0,程序的整個(gè)運(yùn)行過程中,當(dāng)前對象的內(nèi)存就一直不回被回收
2)引用計(jì)數(shù)器的三種操作
(1)retain(給對象發(fā)送消息一條retain消息) ? 計(jì)數(shù)器+1,有返回值,返回的是對象本身
(2)release (給對象發(fā)送消息一條release消息)計(jì)數(shù)器-1。無返回值。
(3)retainCount (給對象發(fā)送消息一條retainCount消息)獲取當(dāng)前對象的引用計(jì)數(shù)器值
3.當(dāng)對象銷毀時(shí)系統(tǒng)會(huì)自己主動(dòng)調(diào)用dealloc方法,dealloc方法就像臨終遺言一樣,所以我們一般重寫dealloc方法
而且此方法中,一定要有[super dealloc] ,且一定放在最后面。
3.如果我們有一個(gè)Person 類
#import <Foundation/Foundation.h >
@interface Person : NSObject
{
{
int _age ;
}
-(void)setAge:(int)age;
-(int)age;
}
#import"Person.h"
@implementation Person
{
-(void)setAge:(int)age{
_age = age ;
}
-(int)age{
return _age;}
-(void)dealloc{
NSLog(@"Person 對象被回收");
[super dealloc]。
}
(1)第一種情況
int main(){
//當(dāng)我們一調(diào)用alloc時(shí),對象計(jì)數(shù)器就默覺得1。所以一有alloc ,我們須在后面加上[對象名 release]
//p-1(當(dāng)前計(jì)數(shù)器為1)
Person *p =[[Person alloc] init];
//p-2(當(dāng)前計(jì)數(shù)器為2)
[p retain];
//release表示計(jì)數(shù)器減1,此時(shí)p-1
[p ?release];
//p-0,這時(shí)系統(tǒng)會(huì)回收對象p ,運(yùn)行對象p的dealloc方法
[p ?release];
return 0;
}
(2)另外一種情況
int main(){
//當(dāng)我們一調(diào)用alloc時(shí),對象計(jì)數(shù)器就默覺得1。
所以一有alloc ,我們須在后面加上[對象名 release]
//p-1(當(dāng)前計(jì)數(shù)器為1)
Person *p =[[Person alloc] init];
//p-2(當(dāng)前計(jì)數(shù)器為2)
[p retain];
//release表示計(jì)數(shù)器減1,此時(shí)p-1
[p ?release];
//p-0,這時(shí)系統(tǒng)會(huì)回收對象p 。運(yùn)行對象p的dealloc方法
[p ?release]。
//特別。此時(shí)系統(tǒng)已把對象p回收,假設(shè)我們在這里再多次運(yùn)行[p release]的話
//會(huì)訪問僵尸對象(已被系統(tǒng)回收的對象,一塊不可用的內(nèi)存)
//而p這時(shí)則叫野指針(指向僵尸對象的指針),會(huì)造成壞的訪問即EXC_BAD_ACCESS
return 0;
}
如圖:
(3)第三種情況
int main(){
//當(dāng)我們一調(diào)用alloc時(shí),對象計(jì)數(shù)器就默覺得1。所以一有alloc ,我們須在后面加上[對象名 release]
//p-1(當(dāng)前計(jì)數(shù)器為1)
Person *p =[[Person alloc] init];
//p-2(當(dāng)前計(jì)數(shù)器為2)
[p retain];
//release表示計(jì)數(shù)器減1,此時(shí)p-1
[p ?release];
//p-0。這時(shí)系統(tǒng)會(huì)回收對象p ,運(yùn)行對象p的dealloc方法
//運(yùn)行此句的話。假設(shè)不打開Enable Zoombie Object 則不會(huì)報(bào)錯(cuò)
//假設(shè)打開的話。則會(huì)出現(xiàn)這種提示錯(cuò)誤
//message send to deallocated instance
//意思是給已經(jīng)回收的實(shí)例發(fā)送消息
p.age = 10;
return 0;
}
如圖:(4)第四種情況;
int main(){
//當(dāng)我們一調(diào)用alloc時(shí),對象計(jì)數(shù)器就默覺得1。所以一有alloc ,我們須在后面加上[對象名 release]
//p-1(當(dāng)前計(jì)數(shù)器為1)
Person *p =[[Person alloc] init];
//p-2(當(dāng)前計(jì)數(shù)器為2)
[p retain];
//release表示計(jì)數(shù)器減1,此時(shí)p-1
[p ?release];
[p ?release];
//結(jié)合第三種情況。我們就會(huì)這樣想,這時(shí)計(jì)數(shù)器本來是0,我們能夠運(yùn)行retain。計(jì)數(shù)器+1
//我們不就能夠成功運(yùn)行p.age = 10;了嗎 其實(shí),回收的對象是不可能死而復(fù)生的。
//運(yùn)行的結(jié)果如上圖。
//message send to deallocated instance
//意思是給已經(jīng)回收的實(shí)例發(fā)送消息
p.age = 10;
return 0;
}
總結(jié)
以上是生活随笔為你收集整理的关于OC的内存管理-01的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP 用each 和list配合 达到
- 下一篇: PHP设计模式系列 - 解释器模式