一个变量传入方法中更改值,为何出方法后值没变?经典面试题图解

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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。