//自定義類物件實現copy需要遵守copy協議(否則程式崩潰),實現必須實現的協議方法,裡面的程式碼就決定了你的copy是深是淺
#import <Foundation/Foundation.h>
#import "Student.h" //介面部分
// @interface Student : NSObject//<NSCopying/*copy協議*/,NSCoding/*歸檔協議*/>
//
//@property(nonatomic,copy)NSString *name;
//@property(nonatomic,assign)int Age;
//
//@end int main(int argc, const char * argv[])
{
@autoreleasepool
{
Student *student = [[Student alloc] init];
student.name = @"liuguan";
student.Age = ;
NSLog(@"%@",student);
Student *student1 = [student copy];//深複製
//協議實現方式
/***************************
//如果直接return self,則是淺拷貝,如果使用alloc,則是深拷貝
- (id)copyWithZone:(NSZone *)zone
{
Student *stu = [Student allocWithZone:zone];
// Student *stu = [[[[self class] allocWithZone:zone]init]autorelease];// ARC
// stu.name = self.name;
// stu.Age = self.Age;
stu.name = [self.name copy];
stu.Age = self.Age;
NSLog(@"%p***%p",stu.name,self.name);//0x100002078***0x100002078地址一致(淺copy)
return stu;
}//相當於stu的地址等於self的地址,但是這個地址是新開闢的,所以跟copy接收者就沒關係了
***************************/ //Student *student1 = [student copy];//淺複製 // 協議實現方式
/*************************
//- (id)copyWithZone:(NSZone *)zone
//{
// return self;//直接相等
//}//相當於self的地址直接等於copy接受者的地址
相當於 Student *student1 = student ;
***************************/
student1.name = @"wangxinag";
NSLog(@"%@",student1);
NSLog(@"%@",student);
}
return ;
}
在這裡首先提及的就是定義屬性是用的屬性列表中的copy
@property(nonatomic,copy)NSString *name;
在這裡我定義了一個Person類,此處不再陳述
下面是程式碼
Person *p = [[Person alloc] init];
NSMutableString *s = [[NSMutableString alloc] initWithFormat:@"123"];
p.name = s; //此時,name的值為@"123"
NSLog(@"**%@",p.name);
[s appendString:@"world"];
NSLog(@"%@",p.name);
NSLog(@"%p---%p",s,p.name);
輸出結果:
**123
123
0x100206e00---0x100206cf0
可以看出可變字串的值賦給了屬性name,但是地址變化了,在第一次輸出123後邊我又對s進行了重新賦值為world,但是並未影響到p.name的值,這也就驗證了地址確實不同了。其實它內部是通過
- (void)setName:(NSMutableString *)name
{
if(_name != name){ //判斷是否需要重新賦值
[_name release]; //釋放舊引用,計數器-1
_name = [name copy]; //重新賦值,使用copy********就是這裡*********
}
}
進行了深複製。因為s是可變陣列,所以copy之後會開闢一個新的地址空間。假如s是不可變陣列,那麼就會進行淺複製
假如把程式碼改成:
Person *p = [[Person alloc] init];
NSString *s = @"123";
p.name = s; //此時,name的值為@"123"
NSLog(@"%@",p.name);
NSLog(@"%p---%p",s,p.name);
輸出結果:
123
0x100001068---0x100001068
地址是一樣的,說明進行了淺複製
總結:
NSString *s2 = [s1 copy];//八種情況中(s1:mutableString/String;s2:mutableString/String;copy/mutableCopy),只有s1為不可變和利用copy方法 同時滿足時為淺複製,其餘為深複製
那麼為什麼淺複製地址不變呢?