【问题标题】:Why do the variables behave so strange?为什么变量的行为如此奇怪?
【发布时间】:2009-04-29 11:40:08
【问题描述】:

我认为objective-c 中的变量只是对内存中某处对象的引用。所以根据我的理解,结果一定是“一”,因为最后我将对象的内存地址str1分配给了str2,而之前我已经分配了str2的内存地址来测试。

NSString *str1 = [NSString stringWithCString:"one"];
NSString *str2 = [NSString stringWithCString:"two"];

test = str2; // test is an instance variable. I use no getter/setter here! just for testing!
str2 = str1;
NSLog(test); // = "two" ??

【问题讨论】:

标签: objective-c cocoa memory-management variables object


【解决方案1】:

这就是指针的工作方式。您看到的结果是正常且正确的。

让我们列出所有变量以及它们在声明时在内存中指向的字符串:

str1 -> "One"
str2 -> "Two"

然后,你执行一些赋值指令:

test = str2;

这会将指针str2 的值分配给test。所以指针是

str1 -> "One"
str2 -> "Two"
test -> "Two"

然后

str2 = str1;

将指针@​​987654327@ 的值分配给str2。现在指针是

str1 -> "One"
str2 -> "One"
test -> "Two"

然后你打印test,它指向str2最初指向的东西,即“二”。

我认为您认为既然您将str2 分配给str1 的值,并将test 分配给str2 的值,那么str1 的值会以某种方式级联到test。不是这种情况。一旦分配了test 的值,有关该值来自何处的信息就会丢失。如果您希望test 的值与str1 的值相同,则需要颠倒赋值操作的顺序:

str2 = str1;
test = str2;

【讨论】:

  • 感谢。我觉得我现在已经明白了。那么这些指针总是返回值,而不是对象本身的内存地址?
  • 嗯,不。变量的值是一个地址,就像你想象的那样。只是没有“级联”的作业。
【解决方案2】:

你有这个:

test = str2; // test is an instance variable.testing!
str2 = str1;
NSLog(test); // = "two" ??

现在,让我们假设所有这些变量都是整数。

在第一行,变量test 设置为变量str2 的值。 在第二行,变量str2 设置为变量str1 的值。 在第三行,我们打印出test 的值,这确实是我们分配str2 进行测试时str2 的值。 我们随后为 str2 分配了一个不同的值真的没关系。

好的,但是变量实际上是指针,你说,而不是整数。

不管:将指针视为一个数字,即内存中某处的地址。并且将它传递给 NSLog 使得 NSLog 打印的不是指针的值,而是指针指向的值,它是一个 char 数组。

【讨论】:

  • 谢谢。所以说变量的值总是一个内存地址是正确的吗?并且在该地址的“位置”是实际值、对象或其他什么?
  • 或者再试一次:变量总是指向一个内存地址。内存地址后面总是一个特定的值或对象。对吗?
  • 另一个问:每次我使用对象时,代表它们的变量都是“指针”,对吧?
  • 不,只有指针指向内存地址。例如,一个 int 就没有。一个对象变量可能是一个指针。
  • 当我查看 XCode 调试器时,一个 int var 在“value”中显示值,而一个 object var(指针)在“value”中显示类似于内存地址的东西。我认为灯泡现在变得更亮了一点;)
【解决方案3】:

变量是一个容器。该作业将右侧的任何内容放入左侧的任何内容中。换句话说,它将值从一个变量复制到另一个变量;在这种情况下,这些值是指针(内存地址)。

这就是你所做的:

  1. 获取str2 变量中的地址,并将相同的地址放入test 变量中。
  2. 获取str1 变量中的地址,并将相同的地址放入str2 变量中。

第 2 步不影响 test 变量;您对该变量的唯一分配是在第 1 步中。

重要提示:您没有复制 地址的内容;您正在复制地址本身。仍然只有一个“two”字符串,但在第 1 步和第 2 步之间,该对象的地址str2test 中。然后,在第 2 步中,将str2 中的地址替换为“one”字符串的地址,该地址也存在于str1 中,留下test 作为唯一仍然保存“two”地址的变量字符串。

顺便说一句,stringWithCString: 已弃用。请改用stringWithUTF8String:stringWithCString:encoding:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 2018-07-21
    • 2018-09-13
    • 1970-01-01
    • 2021-10-27
    相关资源
    最近更新 更多