2

Take a look at this:

#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;
}  

The console log is:

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

Notice the address of str is the main function and the address of str1 in method1 is same until str1 is reassigned. Does this follow the principle of passing by Value?

Yes, the value and address of str remains the same after the control comes back to main which follows the principle of passing by value.

So can anyone explain this, or should we live with the fact that str is passed by value and not by reference.

Raunak
  • 3,314
  • 1
  • 22
  • 28

2 Answers2

3

First of all, "objects" are not values in Objective-C. You cannot have an expression of "object" type -- the compiler would complain if you did something like this:

NSString foo;

Rather, you can only have object pointers. Everything you can do to objects, you do through object pointers. In your code, str, str1, etc. are object pointer variables.

With that out of the way, Objective-C is indeed always pass-by-value. Your question doesn't really make sense because "objects" are not passed or assigned. ("Objects" are not values in the first place.) In your example, your methods take object pointers.

As always with pass-by-value, assignments to local variables do not affect outside code.

newacct
  • 119,665
  • 29
  • 163
  • 224
1

Actually, if object parameters would really be passed by value, you would see exactly the opposite behavior. It is precisely because they are being passed by reference that the address of str1 is the same in main and method1 – you just have two references (str and str1) to the same pointer.

omz
  • 53,243
  • 5
  • 129
  • 141
  • So, by which you mean to say that str1 is passed by reference. Then how would (NSString **) be passed? And have a look at http://stackoverflow.com/questions/2892520/passing-arguments-by-value-or-by-reference-in-objective-c . – Raunak Sep 11 '12 at 11:13
  • 1
    They are passed by value but you are passing __pointers__. And passing a pointer by value is equivalent to passing object by reference. – Sulthan Sep 11 '12 at 11:40
  • By which you mean to say that str is being the object in this case is being passed by reference? Which means when I say str1 = @"foo" in method1 and log the value of str in main then str should be @"foo" but str is still @"moo" when the control comes back to main. – Raunak Sep 11 '12 at 11:45