内存管理Memorynbsp;OC——第九天
生活随笔
收集整理的這篇文章主要介紹了
内存管理Memorynbsp;OC——第九天
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1、? ? 內(nèi)存管理方式 ? ? ? ? 垃圾回收機(jī)制:(Garbage Collection),有系統(tǒng)管理內(nèi)存,開(kāi)發(fā)人員需要管理 ? ? ? ? 注:OC從2.0之后就開(kāi)始支持垃圾回收機(jī)制,但是只適用于OS開(kāi)發(fā),(蘋(píng)果電腦的操作系統(tǒng)),我們iOS平臺(tái)是不支持垃圾回收機(jī)制;(面試題) 不支持垃圾回收機(jī)制,OC是如何管理內(nèi)存的呢? ??????? //內(nèi)存不釋放 就叫內(nèi)存泄露 //OC通過(guò)引入計(jì)數(shù)器管理內(nèi)存
??????? //圖中需要照明的人數(shù),就代表引用計(jì)數(shù)
??????? //1.當(dāng)?shù)谝蝗?#34;需要照明",引用計(jì)數(shù)+1 ??? 有0-->1
??????? //2.當(dāng)?shù)诙€(gè)人"需要照明",引用計(jì)數(shù)+1 ??? 有1-->2
??????? //3.當(dāng)?shù)诙€(gè)人"需要照明",引用計(jì)數(shù)+1 ??? 有2-->3
??????? //4.當(dāng)有一個(gè)人"不需要照明",引用計(jì)數(shù)-1 ??? 有3-->2
??????? //5.當(dāng)再有一個(gè)人"不需要照明",引用計(jì)數(shù)-1 ??? 有2-->1 ??????? //6.當(dāng)再有一個(gè)人"不需要照明",引用計(jì)數(shù)-1 ??? 有1-->0 2、iOS平臺(tái)下適用計(jì)數(shù)器如何管理內(nèi)存,有兩種方式 ? ?? 1.MRC:(Manual Reference Counting),手動(dòng)引入計(jì)數(shù)器,有開(kāi)發(fā)人員通過(guò)手動(dòng)引入計(jì)數(shù)器來(lái)管理內(nèi)存。 ? ? ? 2.ARC:(Automatic Reference Counting),自動(dòng)引入計(jì)數(shù)器,由系統(tǒng)通過(guò)引入計(jì)數(shù)器管理內(nèi)存 ??????? //學(xué)習(xí)好MRC是為了更好使用ARC,iOS5.0之后就有了ARC; ARC和MRC的混編 ? ? ? ? 1.如果工程環(huán)境是ARC,而部分文件使用了MRC,使用一個(gè)參數(shù)??? -fno-objc-arc ? ? ? ? 2.如果工程環(huán)境是MRC,而部分文件使用了ARC,使用一個(gè)參數(shù) ??? -fobjc-arc ============================================================== 例子:? 1.自己創(chuàng)建的對(duì)象自己持有; Person.h @interface Person : NSObject //名字的屬性 @property (nonatomic,copy)NSString *name; @end
Person.m @implementation Person
//dealloc 方法是對(duì)象被銷(xiāo)毀的時(shí)候自動(dòng)調(diào)用的方法,不需要手動(dòng)調(diào)用,由于dealloc方法是重寫(xiě)的父類(lèi),所以重寫(xiě)此方法的時(shí)候,一定要把父類(lèi)的方法內(nèi)容也寫(xiě)上 - (void)dealloc? ?{ ??NSLog(@"Person%@對(duì)象被銷(xiāo)毀了",_name);
??? //以后重寫(xiě)dealloc方法時(shí)一定調(diào)用[super dealloc];? 且此方法一定要寫(xiě)在最下面 ??? [super dealloc]; } @end
main.m Person *p = [[Person alloc]init];//alloc會(huì)造成對(duì)象的引用計(jì)數(shù)器由0-->1 ??????? p.name = @"緩緩"; ??????? //如何判斷一個(gè)對(duì)象是否被持有,就看它的引用計(jì)數(shù)
??????? //retainCount :對(duì)象的引用計(jì)數(shù) ??????? NSLog(@"%lu",p.retainCount); //計(jì)數(shù)器為1 ??????? //如果自己創(chuàng)建的對(duì)象不使用時(shí),釋放對(duì)象,使用release
??????? [p release];
// ??? NSLog(@"%lu",p.retainCount); ????? 對(duì)象死了就不能再使用它了 // ??? [p release];??? 不要過(guò)度釋放,也等于操作僵尸對(duì)象 ?Person *p2 = [[Person alloc]init]; ? //0--->1 ??????? p2.name = @"武媚娘"; 3、retain可以讓對(duì)象的引用計(jì)數(shù) +1
??????? //非自己創(chuàng)建的對(duì)象,自己也能持有
???????? p2 =? [p2 retain]; //由1--->2
??????? NSLog(@"%lu",p2.retainCount);
???????
???????? //非自己創(chuàng)建的對(duì)象,自己也能持有
??????? Person *p3 = [p2 retain];
??????? NSLog(@"%lu",p3.retainCount);? //2--->3
??????? [p2 release];//3-->2
??????? [p2 release];//2-->1
??????? [p3 release];//1-->0
???????
??????? Person *p4 = [[Person alloc]init];
??????? p4.name = @"小骨";
??????? [p4 retain];//2
??????? [p4 retain];//3
??????? [p4 retain];//4
??????? [p4 release];//3
??????? [p4 release];//2
??????? [p4 release];//1 ??????? [p4 release];//0 // ? ?? [p4 retain];//人死不能復(fù)生,對(duì)象死也不能復(fù)生 4、 方法的基本使用 ? ? ? ? 1.retain : 計(jì)算器 +1 ? ,會(huì)返回對(duì)象本身;(返回值為id泛類(lèi)型) ? ? ? ? 2.release : 計(jì)數(shù)器 - 1,沒(méi)有返回值 ? ? ? ? 3.retainCount 的作用:獲取當(dāng)前對(duì)象的計(jì)數(shù)器數(shù)值 ? ? ? ??4.dealloc 當(dāng)一個(gè)對(duì)象被銷(xiāo)毀的時(shí)候,系統(tǒng)會(huì)自動(dòng)調(diào)用,再次方法中一定要調(diào)用[super delloc];且這句話要放到最后; 5、 概念 ? ? //僵尸對(duì)象:所占內(nèi)存被回收的對(duì)象,就叫僵尸對(duì)象,僵尸對(duì)象不能再使用 ??????? //野指針:指僵尸對(duì)象的指針就叫野指針 ??????? //空指針:沒(méi)有志向任何東西的指針就叫空指針叫空指針,(nil,NULL,0),給空指針發(fā)送消息
??????? // ? alloc 對(duì)應(yīng)? dealloc ??????? //? retain? 對(duì)應(yīng) release ? ? ? ? 區(qū)別: [[Person alloc]init]; ? 內(nèi)存永遠(yuǎn)不會(huì)被釋放 ??????? //??????? [[[Person alloc]init]release];? 創(chuàng)建的同時(shí)立即就被釋放掉 ??????? //autorelease 相比 release,也能造成引用計(jì)數(shù)器-1,不過(guò)autorelease 不是立即-1,會(huì)在未來(lái)某段時(shí)間做-1操作; 6、 autorelease 執(zhí)行實(shí)質(zhì),對(duì)一個(gè)對(duì)象使用autorelease 操作,這個(gè)對(duì)象的引用計(jì)數(shù)器不會(huì)立即減1,如果把這個(gè)autorelease? 操作放到自動(dòng)釋放出中,會(huì)在出池子的一瞬間減1,如果你沒(méi)有放到池子中,不會(huì)對(duì)autorelease? 操作對(duì)象進(jìn)行減1; ?注意:你要使用autorelease 必須和自動(dòng)釋放池配合使用 //??????? Person *p5 = [[Person alloc]init];//0--->1 // ? ? ? ?p5.name = @"殺阡陌"; //??????? [p5 autorelease];//1 //??????? NSLog(@"%lu",p5.retainCount); ======================================================= 7、創(chuàng)建自動(dòng)釋放池的兩種形式
??????? //第一種形式 // ? ?NSAutoreleasePool? 自動(dòng)釋放池類(lèi) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
??????? Person *p6 = [[Person alloc]init];
??????? p6.name = @"白子畫(huà)";
??????? [p6 autorelease];//或者用[p6 release];
??????? NSLog(@"%lu",p6.retainCount);
??????? [pool release];
???????
??????? //第二種形式
??????? @autoreleasepool {
??????????? Person *p7 = [[Person alloc]init];
??????????? p7.name = @"糖寶";
??????????? [p7 autorelease];//未來(lái)的時(shí)間減1,出自動(dòng)釋放池減1
//??????????? [p7 release];//-1 ??? //過(guò)度釋放
??????????? NSLog(@"%lu",p7.retainCount); ??? }//此時(shí)也會(huì)引起過(guò)度釋放,是由autorelease引起的 8、 內(nèi)存管理的原則
??????? //水污染誰(shuí)治理,誰(shuí)alloc誰(shuí)release,誰(shuí)return誰(shuí)release,autorelease
??????? //你想占用某個(gè)對(duì)象,就應(yīng)該讓對(duì)象的計(jì)數(shù)+1,(也就是讓對(duì)象做以retain操作) ??????? //當(dāng)你不想持有(占有)某個(gè)對(duì)象時(shí),就應(yīng)該讓對(duì)象的引用計(jì)數(shù)-1,(也就是讓對(duì)象做一release操作) 重復(fù)使用的釋放可以設(shè)置帶有參數(shù)的宏定義,減少繁瑣的程序 #define kRelease_Safe(_point) [_point release];_point = nil; ??????? Person *p8 = [[Person alloc]init]; ??????? p8.name = @"紫熏"; ??????? Person *p9 = [p8 retain]; ? ? ? ? kRelease_Safe(p8); ??????? NSLog(@"%@",p9.name); ? ? ? ? kRelease_Safe(p9);? //??????? [p8 release];//對(duì)一個(gè)空指針發(fā)送消息,沒(méi)有任何影響 9、 NSMutableArray *mArray = [[NSMutableArray alloc]initWithCapacity:0];
??????? //向數(shù)組中添加十個(gè)人
??????? for (int i = 0; i < 10 ; i ++) {
??????????????? Person *person = [[Person alloc]init];
??????????????? person.name = [NSString? stringWithFormat:@"%d",i];
??????????????? //數(shù)組在添加元素的時(shí)候,會(huì)對(duì)添加的元素做一次retain操作
??????????????? [mArray addObject:person];
??????????????? kRelease_Safe(person); ??????? } ??????? NSLog(@"%@",mArray);
??????? //數(shù)組在釋放自己之前,會(huì)對(duì)之前添加到數(shù)組中的元素進(jìn)行引用計(jì)數(shù)減1的操作 ??????? kRelease_Safe(mArray); ??????? //此時(shí)我們沒(méi)有alloc 也沒(méi)有retain ,所以不需要對(duì)數(shù)組mArray2 的內(nèi)存釋放負(fù)責(zé)
??????? NSMutableArray *mArray2 = [NSMutableArray array];//
??????? Person *p10 = [[Person alloc]init];
??????? p10.name = @"朱然";
??????? [mArray2 addObject:p10]; ??????? kRelease_Safe(p10); ??????? NSString *string = [[NSString alloc]initWithString:@"12345678912345"]; ??????? NSLog(@"%ld",string.retainCount); ?總結(jié):非重點(diǎn),但是考試一般會(huì)問(wèn)及: 當(dāng)使用stringWithFormat:創(chuàng)建的字符串對(duì)象當(dāng)長(zhǎng)度小于10的時(shí)候,在常量區(qū);大于等于10的時(shí)候,在堆區(qū);
????????? //使用其他方法創(chuàng)建的字符串都在常量區(qū)
??????? NSString *string2 = [NSString stringWithFormat:@"1234567890"]; ??????? NSLog(@"%lu",string2.retainCount); ??????? //沒(méi)人去釋放字符串,stringWithFormat:? 計(jì)數(shù)器1,其他計(jì)數(shù)為-1; ====================================================== 10、 copy 對(duì)象能夠使用copy操作的前提是,此類(lèi)必須遵循NSCopying 協(xié)議 ??????? //淺拷貝,只拷貝地址,同時(shí)對(duì)象的引用計(jì)數(shù)+1;此時(shí)拷貝出來(lái)的對(duì)象原對(duì)象的所占的空間大小相等,內(nèi)容也相等 ??????? //深拷貝 不止拷貝空間和內(nèi)容,而且從新開(kāi)辟了一塊內(nèi)存 區(qū)別:淺拷貝會(huì)造成原對(duì)象的引用計(jì)數(shù)加+1,而深拷貝不會(huì)造成原對(duì)象的計(jì)數(shù)加+1; ? ? 例子:在Person類(lèi)基礎(chǔ)上舉例 Person.h #import @interface Person : NSObject<</span>NSCopying>必須遵循NSCopying 協(xié)議 //名字的屬性 @property (nonatomic,copy)NSString *name; @end
Person.m - (void)dealloc{ ? NSLog(@"Person%@對(duì)象被銷(xiāo)毀了",_name); ??? [super dealloc]; } - (id)copyWithZone:(NSZone *)zone{
??? //返回對(duì)象的時(shí)候要做一次retain操作,外界的接受者才持有這個(gè)對(duì)象 ? ? // return [self retain]; //深拷貝? 返回的是新的對(duì)象,此時(shí)兩個(gè)對(duì)象所占的空間大小相同,內(nèi)容也相同
??? Person *p = [[Person allocWithZone:zone]init]; ??? p.name = self.name; ??? return p; } @end
main.m ? Person *p11 = [[Person alloc]init];
??????? p11.name = @"笙蕭默";
??????? Person *p12 = [p11 copy];
??????? NSLog(@"%@",p12.name); ??????? NSLog(@"p11 = %p p12 = %p ",p11,p12); ? ? ? ??????? kRelease_Safe(p11); ??????? kRelease_Safe(p12); ===================================================== 11、 new? 申請(qǐng)創(chuàng)建對(duì)象的同時(shí)讓其引用計(jì)數(shù)0-—>1(不常用) ??????? //new其實(shí)就做了alloc和init 兩步操作,申請(qǐng)空間并初始化
??????? //????? [Person new] = [Person alloc]init];
??????? Person *p13 = [Person new];
??????? p13.name = @"東方"; ??????? kRelease_Safe(p13); 總結(jié):內(nèi)存管理的總結(jié) ???????? 1.引用計(jì)數(shù)+1(alloc ,copy , new , retain)
???????? 2.引用計(jì)數(shù) -1 (release , autorelease)
???????? 3.要想內(nèi)存不出現(xiàn)泄漏,引用計(jì)數(shù)-1的次數(shù)相等
???????? 4.一旦引用計(jì)數(shù)為0的時(shí)候系統(tǒng)會(huì)自動(dòng)調(diào)用dealloc 方法 ???????? 5.誰(shuí)污染誰(shuí)治理,誰(shuí)alloc誰(shuí)release,誰(shuí)return誰(shuí)release,autorelease 深入了解學(xué)習(xí): http://blog.sina.com.cn/s/blog_814ecfa90102vuqv.html 歡迎學(xué)習(xí)本文,未經(jīng)許可,不得私自轉(zhuǎn)載!
| 圖中那個(gè)的行為 | ? ? OC中操作 | OC中方法 |
| 根據(jù)照明設(shè)備所做的動(dòng)作 | 對(duì)對(duì)象的操作 | |
| 開(kāi)燈 ? | 生成對(duì)象 | alloc/copy/new |
| 需要照明 | 持有對(duì)象 | return |
| 不需要照明 | 釋放對(duì)象 | release/autorelese(不會(huì)立即釋放且與@autoreleasepool配合使用) |
| 關(guān)燈 | 廢棄對(duì)象 ? | dealloc |
??????? //圖中需要照明的人數(shù),就代表引用計(jì)數(shù)
??????? //1.當(dāng)?shù)谝蝗?#34;需要照明",引用計(jì)數(shù)+1 ??? 有0-->1
??????? //2.當(dāng)?shù)诙€(gè)人"需要照明",引用計(jì)數(shù)+1 ??? 有1-->2
??????? //3.當(dāng)?shù)诙€(gè)人"需要照明",引用計(jì)數(shù)+1 ??? 有2-->3
??????? //4.當(dāng)有一個(gè)人"不需要照明",引用計(jì)數(shù)-1 ??? 有3-->2
??????? //5.當(dāng)再有一個(gè)人"不需要照明",引用計(jì)數(shù)-1 ??? 有2-->1 ??????? //6.當(dāng)再有一個(gè)人"不需要照明",引用計(jì)數(shù)-1 ??? 有1-->0 2、iOS平臺(tái)下適用計(jì)數(shù)器如何管理內(nèi)存,有兩種方式 ? ?? 1.MRC:(Manual Reference Counting),手動(dòng)引入計(jì)數(shù)器,有開(kāi)發(fā)人員通過(guò)手動(dòng)引入計(jì)數(shù)器來(lái)管理內(nèi)存。 ? ? ? 2.ARC:(Automatic Reference Counting),自動(dòng)引入計(jì)數(shù)器,由系統(tǒng)通過(guò)引入計(jì)數(shù)器管理內(nèi)存 ??????? //學(xué)習(xí)好MRC是為了更好使用ARC,iOS5.0之后就有了ARC; ARC和MRC的混編 ? ? ? ? 1.如果工程環(huán)境是ARC,而部分文件使用了MRC,使用一個(gè)參數(shù)??? -fno-objc-arc ? ? ? ? 2.如果工程環(huán)境是MRC,而部分文件使用了ARC,使用一個(gè)參數(shù) ??? -fobjc-arc ============================================================== 例子:? 1.自己創(chuàng)建的對(duì)象自己持有; Person.h @interface Person : NSObject //名字的屬性 @property (nonatomic,copy)NSString *name; @end
Person.m @implementation Person
//dealloc 方法是對(duì)象被銷(xiāo)毀的時(shí)候自動(dòng)調(diào)用的方法,不需要手動(dòng)調(diào)用,由于dealloc方法是重寫(xiě)的父類(lèi),所以重寫(xiě)此方法的時(shí)候,一定要把父類(lèi)的方法內(nèi)容也寫(xiě)上 - (void)dealloc? ?{ ??NSLog(@"Person%@對(duì)象被銷(xiāo)毀了",_name);
??? //以后重寫(xiě)dealloc方法時(shí)一定調(diào)用[super dealloc];? 且此方法一定要寫(xiě)在最下面 ??? [super dealloc]; } @end
main.m Person *p = [[Person alloc]init];//alloc會(huì)造成對(duì)象的引用計(jì)數(shù)器由0-->1 ??????? p.name = @"緩緩"; ??????? //如何判斷一個(gè)對(duì)象是否被持有,就看它的引用計(jì)數(shù)
??????? //retainCount :對(duì)象的引用計(jì)數(shù) ??????? NSLog(@"%lu",p.retainCount); //計(jì)數(shù)器為1 ??????? //如果自己創(chuàng)建的對(duì)象不使用時(shí),釋放對(duì)象,使用release
??????? [p release];
// ??? NSLog(@"%lu",p.retainCount); ????? 對(duì)象死了就不能再使用它了 // ??? [p release];??? 不要過(guò)度釋放,也等于操作僵尸對(duì)象 ?Person *p2 = [[Person alloc]init]; ? //0--->1 ??????? p2.name = @"武媚娘"; 3、retain可以讓對(duì)象的引用計(jì)數(shù) +1
??????? //非自己創(chuàng)建的對(duì)象,自己也能持有
???????? p2 =? [p2 retain]; //由1--->2
??????? NSLog(@"%lu",p2.retainCount);
???????
???????? //非自己創(chuàng)建的對(duì)象,自己也能持有
??????? Person *p3 = [p2 retain];
??????? NSLog(@"%lu",p3.retainCount);? //2--->3
??????? [p2 release];//3-->2
??????? [p2 release];//2-->1
??????? [p3 release];//1-->0
???????
??????? Person *p4 = [[Person alloc]init];
??????? p4.name = @"小骨";
??????? [p4 retain];//2
??????? [p4 retain];//3
??????? [p4 retain];//4
??????? [p4 release];//3
??????? [p4 release];//2
??????? [p4 release];//1 ??????? [p4 release];//0 // ? ?? [p4 retain];//人死不能復(fù)生,對(duì)象死也不能復(fù)生 4、 方法的基本使用 ? ? ? ? 1.retain : 計(jì)算器 +1 ? ,會(huì)返回對(duì)象本身;(返回值為id泛類(lèi)型) ? ? ? ? 2.release : 計(jì)數(shù)器 - 1,沒(méi)有返回值 ? ? ? ? 3.retainCount 的作用:獲取當(dāng)前對(duì)象的計(jì)數(shù)器數(shù)值 ? ? ? ??4.dealloc 當(dāng)一個(gè)對(duì)象被銷(xiāo)毀的時(shí)候,系統(tǒng)會(huì)自動(dòng)調(diào)用,再次方法中一定要調(diào)用[super delloc];且這句話要放到最后; 5、 概念 ? ? //僵尸對(duì)象:所占內(nèi)存被回收的對(duì)象,就叫僵尸對(duì)象,僵尸對(duì)象不能再使用 ??????? //野指針:指僵尸對(duì)象的指針就叫野指針 ??????? //空指針:沒(méi)有志向任何東西的指針就叫空指針叫空指針,(nil,NULL,0),給空指針發(fā)送消息
??????? // ? alloc 對(duì)應(yīng)? dealloc ??????? //? retain? 對(duì)應(yīng) release ? ? ? ? 區(qū)別: [[Person alloc]init]; ? 內(nèi)存永遠(yuǎn)不會(huì)被釋放 ??????? //??????? [[[Person alloc]init]release];? 創(chuàng)建的同時(shí)立即就被釋放掉 ??????? //autorelease 相比 release,也能造成引用計(jì)數(shù)器-1,不過(guò)autorelease 不是立即-1,會(huì)在未來(lái)某段時(shí)間做-1操作; 6、 autorelease 執(zhí)行實(shí)質(zhì),對(duì)一個(gè)對(duì)象使用autorelease 操作,這個(gè)對(duì)象的引用計(jì)數(shù)器不會(huì)立即減1,如果把這個(gè)autorelease? 操作放到自動(dòng)釋放出中,會(huì)在出池子的一瞬間減1,如果你沒(méi)有放到池子中,不會(huì)對(duì)autorelease? 操作對(duì)象進(jìn)行減1; ?注意:你要使用autorelease 必須和自動(dòng)釋放池配合使用 //??????? Person *p5 = [[Person alloc]init];//0--->1 // ? ? ? ?p5.name = @"殺阡陌"; //??????? [p5 autorelease];//1 //??????? NSLog(@"%lu",p5.retainCount); ======================================================= 7、創(chuàng)建自動(dòng)釋放池的兩種形式
??????? //第一種形式 // ? ?NSAutoreleasePool? 自動(dòng)釋放池類(lèi) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
??????? Person *p6 = [[Person alloc]init];
??????? p6.name = @"白子畫(huà)";
??????? [p6 autorelease];//或者用[p6 release];
??????? NSLog(@"%lu",p6.retainCount);
??????? [pool release];
???????
??????? //第二種形式
??????? @autoreleasepool {
??????????? Person *p7 = [[Person alloc]init];
??????????? p7.name = @"糖寶";
??????????? [p7 autorelease];//未來(lái)的時(shí)間減1,出自動(dòng)釋放池減1
//??????????? [p7 release];//-1 ??? //過(guò)度釋放
??????????? NSLog(@"%lu",p7.retainCount); ??? }//此時(shí)也會(huì)引起過(guò)度釋放,是由autorelease引起的 8、 內(nèi)存管理的原則
??????? //水污染誰(shuí)治理,誰(shuí)alloc誰(shuí)release,誰(shuí)return誰(shuí)release,autorelease
??????? //你想占用某個(gè)對(duì)象,就應(yīng)該讓對(duì)象的計(jì)數(shù)+1,(也就是讓對(duì)象做以retain操作) ??????? //當(dāng)你不想持有(占有)某個(gè)對(duì)象時(shí),就應(yīng)該讓對(duì)象的引用計(jì)數(shù)-1,(也就是讓對(duì)象做一release操作) 重復(fù)使用的釋放可以設(shè)置帶有參數(shù)的宏定義,減少繁瑣的程序 #define kRelease_Safe(_point) [_point release];_point = nil; ??????? Person *p8 = [[Person alloc]init]; ??????? p8.name = @"紫熏"; ??????? Person *p9 = [p8 retain]; ? ? ? ? kRelease_Safe(p8); ??????? NSLog(@"%@",p9.name); ? ? ? ? kRelease_Safe(p9);? //??????? [p8 release];//對(duì)一個(gè)空指針發(fā)送消息,沒(méi)有任何影響 9、 NSMutableArray *mArray = [[NSMutableArray alloc]initWithCapacity:0];
??????? //向數(shù)組中添加十個(gè)人
??????? for (int i = 0; i < 10 ; i ++) {
??????????????? Person *person = [[Person alloc]init];
??????????????? person.name = [NSString? stringWithFormat:@"%d",i];
??????????????? //數(shù)組在添加元素的時(shí)候,會(huì)對(duì)添加的元素做一次retain操作
??????????????? [mArray addObject:person];
??????????????? kRelease_Safe(person); ??????? } ??????? NSLog(@"%@",mArray);
??????? //數(shù)組在釋放自己之前,會(huì)對(duì)之前添加到數(shù)組中的元素進(jìn)行引用計(jì)數(shù)減1的操作 ??????? kRelease_Safe(mArray); ??????? //此時(shí)我們沒(méi)有alloc 也沒(méi)有retain ,所以不需要對(duì)數(shù)組mArray2 的內(nèi)存釋放負(fù)責(zé)
??????? NSMutableArray *mArray2 = [NSMutableArray array];//
??????? Person *p10 = [[Person alloc]init];
??????? p10.name = @"朱然";
??????? [mArray2 addObject:p10]; ??????? kRelease_Safe(p10); ??????? NSString *string = [[NSString alloc]initWithString:@"12345678912345"]; ??????? NSLog(@"%ld",string.retainCount); ?總結(jié):非重點(diǎn),但是考試一般會(huì)問(wèn)及: 當(dāng)使用stringWithFormat:創(chuàng)建的字符串對(duì)象當(dāng)長(zhǎng)度小于10的時(shí)候,在常量區(qū);大于等于10的時(shí)候,在堆區(qū);
????????? //使用其他方法創(chuàng)建的字符串都在常量區(qū)
??????? NSString *string2 = [NSString stringWithFormat:@"1234567890"]; ??????? NSLog(@"%lu",string2.retainCount); ??????? //沒(méi)人去釋放字符串,stringWithFormat:? 計(jì)數(shù)器1,其他計(jì)數(shù)為-1; ====================================================== 10、 copy 對(duì)象能夠使用copy操作的前提是,此類(lèi)必須遵循NSCopying 協(xié)議 ??????? //淺拷貝,只拷貝地址,同時(shí)對(duì)象的引用計(jì)數(shù)+1;此時(shí)拷貝出來(lái)的對(duì)象原對(duì)象的所占的空間大小相等,內(nèi)容也相等 ??????? //深拷貝 不止拷貝空間和內(nèi)容,而且從新開(kāi)辟了一塊內(nèi)存 區(qū)別:淺拷貝會(huì)造成原對(duì)象的引用計(jì)數(shù)加+1,而深拷貝不會(huì)造成原對(duì)象的計(jì)數(shù)加+1; ? ? 例子:在Person類(lèi)基礎(chǔ)上舉例 Person.h #import @interface Person : NSObject<</span>NSCopying>必須遵循NSCopying 協(xié)議 //名字的屬性 @property (nonatomic,copy)NSString *name; @end
Person.m - (void)dealloc{ ? NSLog(@"Person%@對(duì)象被銷(xiāo)毀了",_name); ??? [super dealloc]; } - (id)copyWithZone:(NSZone *)zone{
??? //返回對(duì)象的時(shí)候要做一次retain操作,外界的接受者才持有這個(gè)對(duì)象 ? ? // return [self retain]; //深拷貝? 返回的是新的對(duì)象,此時(shí)兩個(gè)對(duì)象所占的空間大小相同,內(nèi)容也相同
??? Person *p = [[Person allocWithZone:zone]init]; ??? p.name = self.name; ??? return p; } @end
main.m ? Person *p11 = [[Person alloc]init];
??????? p11.name = @"笙蕭默";
??????? Person *p12 = [p11 copy];
??????? NSLog(@"%@",p12.name); ??????? NSLog(@"p11 = %p p12 = %p ",p11,p12); ? ? ? ??????? kRelease_Safe(p11); ??????? kRelease_Safe(p12); ===================================================== 11、 new? 申請(qǐng)創(chuàng)建對(duì)象的同時(shí)讓其引用計(jì)數(shù)0-—>1(不常用) ??????? //new其實(shí)就做了alloc和init 兩步操作,申請(qǐng)空間并初始化
??????? //????? [Person new] = [Person alloc]init];
??????? Person *p13 = [Person new];
??????? p13.name = @"東方"; ??????? kRelease_Safe(p13); 總結(jié):內(nèi)存管理的總結(jié) ???????? 1.引用計(jì)數(shù)+1(alloc ,copy , new , retain)
???????? 2.引用計(jì)數(shù) -1 (release , autorelease)
???????? 3.要想內(nèi)存不出現(xiàn)泄漏,引用計(jì)數(shù)-1的次數(shù)相等
???????? 4.一旦引用計(jì)數(shù)為0的時(shí)候系統(tǒng)會(huì)自動(dòng)調(diào)用dealloc 方法 ???????? 5.誰(shuí)污染誰(shuí)治理,誰(shuí)alloc誰(shuí)release,誰(shuí)return誰(shuí)release,autorelease 深入了解學(xué)習(xí): http://blog.sina.com.cn/s/blog_814ecfa90102vuqv.html 歡迎學(xué)習(xí)本文,未經(jīng)許可,不得私自轉(zhuǎn)載!
總結(jié)
以上是生活随笔為你收集整理的内存管理Memorynbsp;OC——第九天的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【NC204267】牛牛染颜色
- 下一篇: 计算机工作组环境和域环境的区别