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