看看这个:
#import <Foundation/Foundation.h>
@interface ClassA : NSObject
-(NSString *) method1:(NSString*)str1;
@end
@implementation ClassA
-(NSString *) method1:(NSString*)str1
{
NSLog(@"2. %@ at %p", str1, str1);
str1 = @"foo";
NSLog(@"3. %@ at %p", str1, str1);
return str1;
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
NSString *str = @"moo";
NSLog(@"1. %@ at %p", str, str);
ClassA *a = [[ClassA alloc] init];
NSString *b = [a method1:str];
NSLog(@"4. %@ at %p", str, str);
NSLog(@"5. %@ at %p", b, b);
}
return 0;
}
控制台日志是:
2012-09-11 17:03:16.160 passByValue[1559:403] Hello, World!
2012-09-11 17:03:16.162 passByValue[1559:403] 1. moo at 0x104c42248
2012-09-11 17:03:16.162 passByValue[1559:403] 2. moo at 0x104c42248
2012-09-11 17:03:16.163 passByValue[1559:403] 3. foo at 0x104c421e8
2012-09-11 17:03:16.163 passByValue[1559:403] 4. moo at 0x104c42248
2012-09-11 17:03:16.164 passByValue[1559:403] 5. foo at 0x104c421e8
注意str的地址是main函数,在重新分配str1之前,method1中str1的地址是相同的。这是否遵循传递值的原则?
是的,在控制权返回main之后,str的值和地址保持不变,遵循传递值的原则。
所以任何人都可以解释这一点,或者我们应该接受这样一个事实:str是通过值而不是通过引用传递的。
答案 0 :(得分:3)
首先,“对象”不是Objective-C中的值。你不能有“对象”类型的表达式 - 如果你做了类似的事情,编译器会抱怨:
NSString foo;
相反,你只能拥有对象指针。您可以通过对象指针对对象执行所有操作。在您的代码中,str
,str1
等是对象指针变量。
除此之外,Objective-C确实总是按值传递。你的问题没有意义,因为“对象”没有被传递或分配。 (“对象”首先不是值。)在您的示例中,您的方法采用对象指针。
与pass-by-value一样,对局部变量的赋值不会影响外部代码。
答案 1 :(得分:1)
实际上,如果对象参数确实是按值传递的,那么你会看到完全相反的行为。正是因为它们被引用传递,str1
和main
中method1
的地址相同 - 您只有两个引用(str
和{{1 }})到同一个指针。