一.基本原理
為什么要進(jìn)行內(nèi)存管理?
由于移動(dòng)設(shè)備的內(nèi)存有限,所以每個(gè)App所占的內(nèi)存空間也是有限的,當(dāng)App所占用的內(nèi)存較多時(shí),系統(tǒng)就會(huì)發(fā)出內(nèi)存警告,,為了節(jié)省內(nèi)存的使用
當(dāng)對象不再使用內(nèi)存時(shí),需要及時(shí)的對內(nèi)存進(jìn)行回收
管理范圍:任何繼承與NSObject的對象,對其他的基本數(shù)據(jù)類型無效.
對象的基本結(jié)構(gòu):
引用計(jì)數(shù)器:用來保存當(dāng)前對象,有幾個(gè)東西在使用(數(shù)字);
引用計(jì)數(shù)器的作用:用來判斷對象是否應(yīng)該回收內(nèi)存空間,當(dāng)引用計(jì)數(shù)器為0時(shí),此時(shí)需要回收對象的內(nèi)存空間
引用計(jì)數(shù)器的操作:
retain: 引用計(jì)數(shù)器 +1
release: 引用計(jì)數(shù)器 -1
retainCount:得到引用計(jì)數(shù)器的值
對象銷毀
當(dāng)一個(gè)對象的引用計(jì)數(shù)器為0時(shí)乖坠,那么它將被銷毀迫像,其占用的內(nèi)存被系統(tǒng)回收
當(dāng)對象被銷毀時(shí)坦冠,系統(tǒng)會(huì)自動(dòng)向?qū)ο蟀l(fā)送一條dealloc消息算吩,一般會(huì)重寫dealloc方法,在這里釋放相關(guān)的資源岁钓,dealloc就像是對象的“臨終遺言”升略。一旦重寫了dealloc方法就必須調(diào)用[super dealloc],并且放在代碼塊的最后調(diào)用(不能直接調(diào)用dealloc方法)
一旦對象被回收了屡限,那么他所占據(jù)的存儲(chǔ)空間就不再可用降宅,堅(jiān)持使用會(huì)導(dǎo)致程序崩潰(野指針錯(cuò)誤)
內(nèi)存管理原則
(一)原則
只要還有人在使用某個(gè)對象,那么這個(gè)對象就不會(huì)被回收囚霸;
只要你想使用這個(gè)對象,那么就應(yīng)該讓這個(gè)對象的引用計(jì)數(shù)器+1激才;
當(dāng)你不想使用這個(gè)對象時(shí)拓型,應(yīng)該讓對象的引用計(jì)數(shù)器-1;
(二)誰創(chuàng)建瘸恼,誰release
(1)如果你通過alloc,new,copy來創(chuàng)建了一個(gè)對象劣挫,那么你就必須調(diào)用release或者autorelease方法
(2)不是你創(chuàng)建的就不用你去負(fù)責(zé)
(三)誰retain,誰release
只要你調(diào)用了retain东帅,無論這個(gè)對象時(shí)如何生成的压固,你都要調(diào)用release
Autorelease
#pragma mark ----- autorelease ------
//創(chuàng)建對象后,如果想讓對象在出自動(dòng)釋放池的時(shí)候,調(diào)用dealloc方法,那么需要在后面加上autorelease;
//Person *person = [[Person new] autorelease];//引用計(jì)數(shù)1
//此時(shí)person的引用計(jì)數(shù)為0,會(huì)調(diào)用dealloc方法
//[person release];
//
// Person *person = [Person new];
// //此處autorelease是標(biāo)記釋放 并不是真正的釋放,后面仍然可以正常使用對象,一直到autorelease花括號(hào)結(jié)束處,會(huì)調(diào)用dealloc方法
// [person autorelease];
// //不建議,過度釋放
// [person autorelease];
自動(dòng)釋放池創(chuàng)建及簡單使用
NSAutoreleasePool *pool = [NSAutoreleasePool new];//@autoreleasepool{
//
// Person *per2 = [Person new];
// [per2 retain];
//
// //使用屬性的set方法賦值
// per2.name = @"大桶";
//
// //使用KVC方法賦值
// [per2 setValue:@20 forKey:@"age"];
//
// NSLog(@"%@",per2.name);
// NSLog(@"%@",[per2 valueForKey:@"age"]);
//
//
//
//
//
// [per2 release];
//
// [per2 release];
//
// [pool release];//}
//自動(dòng)釋放池嵌套使用
// @autoreleasepool {
// Person *per4 = [[Person new] autorelease];
// }
ARC內(nèi)存管理機(jī)制
(一)ARC的判斷準(zhǔn)則:
只要沒有強(qiáng)指針指向?qū)ο螅瑢ο缶蜁?huì)被釋放靠闭。
(二)指針分類:
(1)強(qiáng)指針:默認(rèn)的情況下帐我,所有的指針都是強(qiáng)指針,關(guān)鍵字strong
(2)弱指針:__weak關(guān)鍵字修飾的指針
聲明一個(gè)弱指針如下:
__weak Person *p;
ARC中愧膀,只要弱指針指向的對象不在了拦键,就直接把弱指針做清空操作。
weak Person *p=[[Person alloc] init];//不合理檩淋,對象一創(chuàng)建出來就被釋放掉芬为,對象釋放掉后,ARC把指針自動(dòng)清零
ARC中在property處不再使用retain,而是使用strong蟀悦,在dealloc中不需要再[super dealloc]媚朦。
@property(nonatomic,strong)Dog *dog;// 意味著生成的成員變量dog是一個(gè)強(qiáng)指針,相當(dāng)于以前的retain日戈。
如果換成是弱指針询张,則換成weak,不需要加