//自定义类对象实现copy需要遵守copy协议(否则程序崩溃),实现必须实现的协议方法,里面的代码就决定了你的copy是深是浅
1 #import <Foundation/Foundation.h>
2 #import "Student.h"
3
4 //接口部分
5 // @interface Student : NSObject//<NSCopying/*copy协议*/,NSCoding/*归档协议*/>
6 //
7 //@property(nonatomic,copy)NSString *name;
8 //@property(nonatomic,assign)int Age;
9 //
10 //@end
11
12 int main(int argc, const char * argv[])
13 {
14 @autoreleasepool
15 {
16 Student *student = [[Student alloc] init];
17 student.name = @"liuguan";
18 student.Age = 21;
19 NSLog(@"%@",student);
20 Student *student1 = [student copy];//深复制
21 //协议实现方式
22 /***************************
23 //如果直接return self,则是浅拷贝,如果使用alloc,则是深拷贝
24 - (id)copyWithZone:(NSZone *)zone
25 {
26 Student *stu = [Student allocWithZone:zone];
27 // Student *stu = [[[[self class] allocWithZone:zone]init]autorelease];// ARC
28 // stu.name = self.name;
29 // stu.Age = self.Age;
30 stu.name = [self.name copy];
31 stu.Age = self.Age;
32 NSLog(@"%p***%p",stu.name,self.name);//0x100002078***0x100002078地址一致(浅copy)
33 return stu;
34 }//相当于stu的地址等于self的地址,但是这个地址是新开辟的,所以跟copy接收者就没关系了
35 ***************************/
36
37
38 //Student *student1 = [student copy];//浅复制
39
40 // 协议实现方式
41 /*************************
42 //- (id)copyWithZone:(NSZone *)zone
43 //{
44 // return self;//直接相等
45 //}//相当于self的地址直接等于copy接受者的地址
46 相当于 Student *student1 = student ;
47 ***************************/
48 student1.name = @"wangxinag";
49 NSLog(@"%@",student1);
50 NSLog(@"%@",student);
51 }
52 return 0;
53 }
在这里首先提及的就是定义属性是用的属性列表中的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方法 同时满足时为浅复制,其余为深复制
那么为什么浅复制地址不变呢?