您好,登錄后才能下訂單哦!
四,關(guān)于語(yǔ)義特性copy和與alloc對(duì)應(yīng)的dealloc以及初始化操作和便利構(gòu)造器的補(bǔ)充
1, 語(yǔ)義特性copy
如果想對(duì)一個(gè)對(duì)象進(jìn)行copy操作,對(duì)象的類必須服從一個(gè)NSCopying協(xié)議,并且實(shí)現(xiàn)協(xié)議中的方法copyWithZone:,方法為(仍以Person類為例):
-(id)copyWithZone:(NSZone*)zone
{
NSString*newSex = [[NSStringallocWithZone:zone]init];
newSex.sex = self.sex;
returnnewSex;
}
其中copyWithZone: 是協(xié)議NSCopying制定的方法,
2, dealloc
對(duì)于dealloc方法,由于系統(tǒng)不知道我們?cè)陂_(kāi)發(fā)程序時(shí)會(huì)對(duì)那些對(duì)象的語(yǔ)義特性聲明為retain或者copy,所以需要我們重寫dealloc方法,即如下:
-(void)dealloc
{
[_namerelease];
[_sexrelease];
NSLog(@"Person空間回收了");
[superdealloc];
}
(1), [_namerelease]和[_sexrelease]操作目的:當(dāng)調(diào)用dealloc方法時(shí),該對(duì)象的空間將要被系統(tǒng)回收,在空間回收之前,將保有的其他對(duì)象()的所有權(quán)給釋放掉,當(dāng)該類對(duì)象的引用計(jì)數(shù)為0時(shí),會(huì)自動(dòng)調(diào)用該類的dealloc方法
(2), [superdealloc]該操作即必須通過(guò)super調(diào)用父類的方法實(shí)現(xiàn),才能將空間回收,
3, 初始化操作
-(id)initWithName:(NSString*)name sex:(NSString *)sex
{
self =[superinit];
if (self) {
self.name = name;
self.sex = sex;
}
returnself;
}
(1),使用self.name = name賦值方法,self.name時(shí)調(diào)用了setter方法,內(nèi)部對(duì)name進(jìn)行了retain操作,即_name也保留了name的使用權(quán),如果使用_name = name即直接賦值方法,則就表示把屬性的語(yǔ)義特性設(shè)為asgin,這時(shí)如果name的空間已經(jīng)被回收了,直接賦值就會(huì)出現(xiàn)野指針問(wèn)題
使用self.sex = sex同理;
(4),便利構(gòu)造器
+(id)teacherWithName:(NSString*)name sex:(NSString *)sex
{
Person*person = [[Person alloc] initWithName:namesex:sex];
return [Personautorelease];
}
我們?cè)谑褂帽憷麡?gòu)造器時(shí)不需要再對(duì)其進(jìn)行release操作,因?yàn)閮?nèi)部已經(jīng)做了autorelease操作,如果在進(jìn)行release操作會(huì)造成過(guò)度釋放,以后我們?cè)賹懕憷麡?gòu)造器就要這樣寫.
五,collection(集合) 的內(nèi)存管理
當(dāng)把一個(gè)對(duì)象放入集合(數(shù)組,字典,集合)中時(shí),會(huì)將對(duì)象的引用計(jì)數(shù) + 1,因?yàn)閮?nèi)部做了retain操作
例如: Person *per1 = [[Personalloc] initWithName:@"Frank"sex:@"boy"];
Person *per2= [[Personalloc] initWithName:@"Duke"sex:@"boy"];
此時(shí)per1和per2所指向的空間的引用計(jì)數(shù)都為1,
NSMutableArray *array =[[NSMutableArray alloc ]initWithObjects:per1,per2, nil];
這里使用便利構(gòu)造器,其內(nèi)部給添加到數(shù)組中的元素進(jìn)行了autorelease操作,這時(shí)per1和per2所指向的空間的引用計(jì)數(shù)都為2,
當(dāng)集合(數(shù)組,字典,集合)空間被回收時(shí),他們會(huì)向容器中的每個(gè)元素發(fā)送一個(gè)release消息(對(duì)應(yīng)添加元素時(shí)的retain操作),當(dāng)從集合(數(shù)組,字典,集合)中移除一個(gè)元素時(shí),會(huì)release該對(duì)象,引用計(jì)數(shù) - 1;
下面把對(duì)該數(shù)組對(duì)象以及存儲(chǔ)的對(duì)象的進(jìn)行release操作
(1),[per1release];
[per2release];
NSLog(@"%lu",[ per1retainCount]);
NSLog(@"%lu",[ per2retainCount]);
此時(shí) per1和per2所指向的空間的引用計(jì)數(shù)都為1, array所指向的空間的引用計(jì)數(shù)為1,
NSLog(@"%@",array); 此時(shí)會(huì)輸出數(shù)組中的內(nèi)容
[per1release];
[per2release];
此時(shí)per1和per2的空間都被回收,因為系統(tǒng)識(shí)別到他們的引用計(jì)數(shù)都為0
NSLog(@"%@",array);此時(shí)若再執(zhí)行該操作系統(tǒng)會(huì)crash,因為數(shù)組中存儲(chǔ)的對(duì)象已經(jīng)被系統(tǒng)回收了,如果輸出相當(dāng)于又對(duì)數(shù)組中被回收的空間進(jìn)行操作,是野指針問(wèn)題
NSLog(@"arrayCount= %lu",[array retainCount]);
此時(shí)array所指向的空間的引用計(jì)數(shù)為1,因?yàn)閍rray的空間沒(méi)有被回收,但不可以輸出數(shù)組
(2),[array release];
此時(shí)array所指向的空間被系統(tǒng)回收
NSLog(@"%lu",[tea1retainCount]);
NSLog(@"%lu",[tea2retainCount]);
此時(shí)per1和per2所指向的空間的引用計(jì)數(shù)都為1,
NSLog(@"%@",array);此時(shí)若再執(zhí)行該操作系統(tǒng)會(huì)crash, 因為數(shù)組已經(jīng)被回收, 如果輸出相當(dāng)于對(duì)被回收的數(shù)組進(jìn)行操作,是野指針問(wèn)題
[per1release];
[per2release];
此時(shí)per1和per2的空間都被回收,因為系統(tǒng)識(shí)別到他們的引用計(jì)數(shù)都為0
NSLog(@"arrayCount= %lu",[array retainCount]);
若進(jìn)行此操作,會(huì)crash, 因?yàn)閍rray的空間已經(jīng)被回收
(3), [per1release];
[per2release];
此時(shí)per1和per2所指向的空間的引用計(jì)數(shù)都為1, array所指向的空間的引用計(jì)數(shù)為1,
[arrayrelease];
此時(shí)array所指向的空間被系統(tǒng)回收,per1和per2的空間也都被回收,當(dāng)集合(數(shù)組,字典,集合)空間被回收時(shí),他們會(huì)向容器中的每個(gè)元素發(fā)送一個(gè)release消息(對(duì)應(yīng)添加元素時(shí)的retain操作),即此時(shí)per1和per2的空間都被回收,因為他們收到了release消息,
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。