NSString *str = @"aaa";
[self change:str];
NSLog(@"%@",str);
- (void)change:(NSString *)str {
str = @"bbb";
}
这道经典的面试题,打印结果是aaa,不是我们想象中的bbb。
那为什么会这样呢?
下面是我画的一个流程图,让大家更容易理解。
注:图中的地址是随意写的,实际肯定不是这样。
1563507797824.jpg
详解:
变量str是一个指针,该指针所在的地址是0x123,它所指向的是字符串@"aaa",字符串@"aaa"地址是0x999。str在传入函数后,函数的形参str是另一个空间0x456,并不是之前的变量str了,形参指向的是变量str所指向的空间0x999也就是字符串@"aaa"。
形参在函数内被赋值 str = @"bbb"; 此时形参0x456指向的就是字符串@"bbb"所在的内存地址0x777。函数外的变量str 0x123依然是指向地址0x999。 在出函数后,形参0x456因为没有引用计数,所以被释放回收。而变量str 0x123依然是指向地址0x999,值为@"aaa"。
思考:
如何在函数体里也能更改掉原来的变量指向的值呢?
答案:将变量的地址传入到函数内,在函数内使这个变量指向另一个值。
NSString *str = @"aaa";
[self change:&str]; // 将变量str的地址传入函数
- (void)change:(NSString **)str { // 这里函数的参数是一个指针变量
*str = @"bbb"; // 直接修改指针变量指向的值
}
再来一个基本类型的例子
int num = 10;
[self change:&num];
- (void)change:(int *)number {
*number = 2;
}