在该实例传递给另一个类之后更改实例属性的结果?

时间:2011-10-14 19:47:37

标签: objective-c

我知道,这是基本的东西。但我一直对此感到困惑。

所以假设我有一个叫做HolderClass的类,它有一个名为changeMe的NSString属性。

我有另一个名为PassedToClass的类,它有一个方法,它将HolderClass的一个实例作为参数,在该方法中,它使用HolderClass的实例来设置一个名为holderInsideOtherClass的属性。

我要将holderClass的实例传递给PassedToClass的实例,如下所示:

HolderClass *demonstrationHolder= [HolderClass new];
PassedToClass *passToMe = [PassedToClass new];

demonstrationHolder.changeMe = @"FirstString";

[passToMe arbitraryMethodThatTakesAHolderClass: demonstrationHolder];

现在,完成此操作后,我可以在两个类中检查changeMe的值:

NSLog (@"%@", demonstrationHolder.changeMe);
NSLog (@"%@", passToMe.holderInsideOtherClass.changeMe);

这两个都应该打印出“FirstString”。

但是现在,如果我这样做会发生什么:

[demonstrationHolder.changeMe = @"SecondString"];

NSLog (@"%@", demonstrationHolder.changeMe);
NSLog (@"%@", passToMe.holderInsideOtherClass.changeMe);

我知道我应该知道这一点,但任何人都可以帮忙吗?

2 个答案:

答案 0 :(得分:3)

保存对象的变量只是指针(内存地址)。当您传递它们或将它们分配给其他变量时,您仍然在完全相同的内存位置引用完全相同的对象。

因此,当您将demonstrationHolder传递到passToMe时,passToMe只会获得对原始对象的引用。如果您将任意位置更改为特定对象,那么这些更改将显示每个包含对该特定对象的引用的代码。这是同一个目标。

当处理可以这种方式改变的对象(“可变”对象)时,通常将属性定义为copy而不是assign / retain / {{1 }}。在这种情况下,您将对象分配给该属性,而不是简单地存储引用,而是创建一个新对象,该对象是原始对象的副本,而是存储对新对象的引用。这意味着将来对原始对象的任何更改都不会影响新副本。

答案 1 :(得分:0)

HolderClass *demonstrationHolder= [HolderClass new];

当执行这行代码时,将为HolderClass的一个实例分配内存,并为该实例指定一个指针(HolderClass *),并将其指定给{{1} }。

获得指针后,您将其分配给demonstrationHolder实例中的成员:

passToMe

这仍然是由[passToMe arbitraryMethodThatTakesAHolderClass: demonstrationHolder]; 表示的相同指针值;它只是一个存储位置,其中存在真实的demonstrationHolder实例。

HolderClass

因为两个指针([demonstrationHolder.changeMe = @"SecondString"]; demonstrationHolder)指向同一个实例,当您使用它们中的任何一个来访问passToMe.holderInsideOtherClass的实例时,您正在修改同一个对象记忆。因此:

HolderClass

这两行都会记录NSLog (@"%@", demonstrationHolder.changeMe); NSLog (@"%@", passToMe.holderInsideOtherClass.changeMe);