Objective-C中的解引用是如何工作的

4

我试图理解Objective-C中的解引用,并编写了以下两种方法。

-(void)alterStringModelOne:(NSMutableString**)string{
    NSMutableString *str = [NSMutableString stringWithString:@"New string by string = &str"];

    string = &str; //Didn't work
}
-(void)alterStringModelTwo:(NSMutableString**)string{
    NSMutableString *str = [NSMutableString stringWithString:@"New string by *string = str"];

    *string = str; //It works
}

以上,ModelOne无法工作而ModelTwo可以。这两个语句有什么不同?

编辑:跟踪它们的地址和类型

myStr = b260 类型为 * CFString

---> 进入模型一方法

string = d9c4 类型为 ** NSMutableString //参数

str = f750 类型为 * CFString //创建 str 后

string = d97c 类型为 ** NSMutableString //分配后:string = &str

--> 方法返回

myStr = b260 类型为 * CFString

--> 进入模型二方法

string = d9c4 类型为 ** NSMutableString //参数

str = 0bc0 类型为 * CFString //创建 str 后

string = 0bc0 类型为 * CFString //分配后:*string = str;

--> 离开方法

myStr = 0bc0 类型为 * CFString


2
第一个方法在普通的C语言中也不会起作用。str是一个本地变量,当你从方法返回时,它的存储就会消失。取它的地址就是取垃圾的地址。 - Hot Licks
如果你有一个返回(void)的方法,但是有一个按引用传递的参数,那么你做错了 - bbum
@bbum 谢谢。但是,正如我所说的,我正在使用解引用来理解它。这段代码并不适用于任何应用程序。 - Saran
2个回答

4

首先:这不仅适用于Objective-C,C和C++也存在同样的行为。

string = &str;

这会修改本地变量string的值。

*string = str;

这会修改由string指向的值。

由于string是一个局部变量,改变它(如第一个示例所示)不会产生任何持久影响。但是,它所指向的值并非本地的,因此更改该值(第二个示例)确实会实现您想要的效果。


谢谢你,duskwuff。现在我能看到了。你能再深入一层吗?我刚刚编辑了通过这个过程捕获每个变量地址的最后四个字符。你能帮我理解当一个地址是 ** 类型时意味着什么吗?或者给我一个链接让我去阅读?我接受这个答案,因为我现在明白了为什么一个有效而另一个无效。 - Saran

0

它的工作方式就像在C语言中一样。Objective-C对象通过指针访问,因此:

NSMutableString *string;

string 被声明为指向对象结构的指针,您可以像直接使用对象一样正常使用它。然后,您传递了该指针的地址,我们将其视为对象本身。类似于:

(NSMutableString **)string

实际上是

((object)*)string

如果你想要给原始对象赋值,你必须使用这个 string 指针所指向的值,而不是它本身(就像在你的第一个模型中发生的那样),否则你最终会修改它所指向的内容,而不是它所代表的地址。这就是为什么你的第二个模型能够工作的原因。你将指向一个对象的指针 str (我们再次认为它只是一个对象)放置在原始指针上,即所谓的由 string 指针指向的对象。

在进行此操作时,请注意内存管理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接