在开发过程中,一直对函数内部修改外部对象的知识抱有怀疑态度,不知道什么情况下可以修改,什么情况下又不可以修改,因此通过demo的方式进行了实践测试。
涉及的知识点:深拷贝、浅拷贝、可变对象、不可变对象、容器等。
浅拷贝就是拷贝后,并没有进行真正的复制,而是复制的对象和原对象都指向同一个地址,也就是同一片内存空间;
深拷贝是真正的复制了一份,复制的对象指向了新的地址,也就是不同的内存空间;
以下几个代表性的例子
字符串
NSString *str = @"字符串";
NSLog(@"方法调用前 str=%@,对象地址=%p,指针地址=%p \n",str,str,&str);
[self changeStrValue:str];
NSLog(@"方法调用后 str=%@,对象地址=%p,指针地址=%p \n",str,str,&str);
- (void)changeStrValue:(NSString *)string{
NSLog(@"方法执行前 str=%@,对象地址=%p,指针地址=%p \n",string,string,&string);
string = @"改变后的字符串";
NSLog(@"方法执行后 str=%@,对象地址=%p,指针地址=%p \n",string,string,&string);
}
打印:
2021-10-19 方法调用前 str=字符串,对象地址=0x1010e6068,指针地址=0x7ffeeeb1a0f0
2021-10-19 方法执行前 str=字符串,对象地址=0x1010e6068,指针地址=0x7ffeeeb1a0b8
2021-10-19 方法执行后 str=改变后的字符串,对象地址=0x1010e61c8,指针地址=0x7ffeeeb1a0b8
2021-10-19 方法调用后 str=字符串,对象地址=0x1010e6068,指针地址=0x7ffeeeb1a0f0
数组
NSMutableArray *arr = [NSMutableArray arrayWithArray:@[@1,@2]];
NSLog(@"方法调用前 str=%@,对象地址=%p,指针地址=%p \n",arr,arr,&arr);
[self changeArray:arr];
NSLog(@"方法调用后 str=%@,对象地址=%p,指针地址=%p \n",arr,arr,&arr);
NSLog(@"%@",arr);
- (void)changeArray:(NSMutableArray *)arr{
NSLog(@"方法执行前 str=%@,对象地址=%p,指针地址=%p \n",arr,arr,&arr);
[arr addObject:@3];
NSLog(@"方法执行后 str=%@,对象地址=%p,指针地址=%p \n",arr,arr,&arr);
}
打印:
2021-10-19 方法调用前 str=( 1, 2 ),对象地址=0x60000248cf00,指针地址=0x7ffeee6280e0
2021-10-19 方法执行前 str=( 1, 2 ),对象地址=0x60000248cf00,指针地址=0x7ffeee628088
2021-10-19 方法执行后 str=( 1, 2, 3 ),对象地址=0x60000248cf00,指针地址=0x7ffeee628088
2021-10-19 方法调用后 str=( 1, 2, 3 ),对象地址=0x60000248cf00,指针地址=0x7ffeee6280e0
2021-10-19 ( 1, 2, 3 )
自定义对象
@interface Model : NSObject
@property (nonatomic , strong) NSString * name;
@property (nonatomic , assign) NSInteger age;
@end
Model *m = [[Model alloc] init];
m.name = @"jim";
m.age = 1;
NSLog(@"方法调用前 m=%@,对象地址=%p,指针地址=%p \n",m,m,&m);
[self changeModel:m];
NSLog(@"方法调用前 m=%@,对象地址=%p,指针地址=%p \n",m,m,&m);
- (void)changeModel:(Model *)model{
NSLog(@"方法执行前 str=%@,对象地址=%p,指针地址=%p \n",model,model,&model);
model.age = 2;
model.name = @"ddd";
NSLog(@"方法执行后 str=%@,对象地址=%p,指针地址=%p \n",model,model,&model);
}
打印:
2021-10-19 方法调用前 m=<Model: 0x60000284cca0>,对象地址=0x60000284cca0,指针地址=0x7ffeebde50f8
2021-10-19 方法执行前 str=<Model: 0x60000284cca0>,对象地址=0x60000284cca0,指针地址=0x7ffeebde50c8
2021-10-19 方法执行后 str=<Model: 0x60000284cca0>,对象地址=0x60000284cca0,指针地址=0x7ffeebde50c8
2021-10-19 方法调用前 m=<Model: 0x60000284cca0>,对象地址=0x60000284cca0,指针地址=0x7ffeebde50f8
参考的网站:
深刻理解iOS中的“深拷贝”和“浅拷贝”