2

看看这个:

#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 是按值传递而不是按引用传递的事实。

4

2 回答 2

3

首先,“对象”不是 Objective-C 中的值。你不能有一个“对象”类型的表达式——如果你做了这样的事情,编译器会抱怨:

NSString foo;

相反,您只能拥有对象指针。你可以对对象做的一切,都是通过对象指针来做的。在您的代码中strstr1, 等是对象指针变量。

除此之外,Objective-C 确实总是按值传递。您的问题没有真正意义,因为“对象”没有被传递或分配。(“对象”首先不是值。)在您的示例中,您的方法采用对象指针。

与按值传递一样,对局部变量的赋值不会影响外部代码。

于 2012-09-11T18:27:05.483 回答
1

实际上,如果对象参数真的按值传递,您会看到完全相反的行为。正是因为它们是通过引用传递的,所以它们的地址在and中str1是相同的——你只有两个对同一个指针的引用 ( and )。mainmethod1strstr1

于 2012-09-11T11:05:11.627 回答