Mayur Mehta
Mayur Mehta

Reputation: 109

Objective-C passing object to function is always by reference or or by value?

In objective-c I am passing NSMutableDictionary to function and modifying it inside function it returns modified mutable dictionary :

NSMutableDictionary *obj2 = [[NSMutableDictionary alloc]initWithObjectsAndKeys:@"hello",@"fname",nil];
[self callerDictionary:obj2];
NSLog(@"%@",obj2[@"fname"]);//printing "Hi"
-(void)callerDictionary:(NSMutableDictionary*)obj
{
    obj[@"fname"] = @"Hi";   
}

Upvotes: 1

Views: 5081

Answers (3)

Paulw11
Paulw11

Reputation: 115051

Technically, Objective C always passes parameter by value, as does C, but practically when you pass an object you need to pass a pointer. While this pointer is passed by value, the semantics of Objective-C give the same effect as if you had passed an object reference; if you modify the objected that is pointed to by the pointer then you are modifying the same object instance that is pointed to in the calling context. The common terminology used in Objective C programming is "object reference" even though it is really a pointer value.

You can see from the * in the method signature that it is a pointer (or object reference in the common usage). If you are passing an intrinsic type, such as an int then it is passed by value unless you explicitly declare the method as requiring a reference:

For example:

-(void) someFunction:(int *)intPointer {
    *intPointer = 5;
}

would be called as

int someInteger = 0;

[self someFunction: &someInteger];

// someInteger is now 5

The distinction between a pointer value and a true object reference can be seen in comparison to Swift which uses true references;

If I have

-(void)someFunction:(NSString *)someString {
     int length = [someString length];
}

and then do

NSMutableArray *array = [NSMutableArray new];
[someFunction: (NSString *)array];

I will get a runtime exception since array doesn't have a length method, but the compiler can't confirm the type I am passing since it is a pointer.

If I attempted the equivalent in Swift then I will get a compile time error since it knows that the type coercion will always fail

Upvotes: 2

Avi
Avi

Reputation: 7552

C and Objective-C always pass parameters by value. Objective-C objects are always accessed through a reference (i.e. a pointer). There is a difference between a variable type (int, pointer, etc.) and the way variables are passed as function parameters. The use of the term reference in both scenarios can cause confusion.

by-value:

void f(int a) {
    a = 14;
}

int a = 5;

NSLog(@"%d", a);  // prints: 5

f(a);

NSLog(@"%d", a);  // prints: 5

The value 5 is printed both times because the function f() is given a copy of the value of a, which is 5. The variable referenced within the function is not the same variable that was passed in; it is a copy.

In C++, you can have functions that take parameters by reference.

by-reference:

void f(int &a) {
    a = 14;
}

int a = 5;

NSLog(@"%d", a);  // prints: 5

f(a);

NSLog(@"%d", a);  // prints: 14

Note the & in the function signature. In C++ (but not C, nor Objective-C), this means that the parameter is passed by reference. What this means is that a reference (pointer) to a is passed to the function. Within the function, the a variable is implicitly dereferenced (remember, it's really a pointer, but you don't treat it as one), and the original a variable declared outside the function is changed.

In C and Objective-C, passing a pointer to a function is functionally equivalent to using a reference parameter in C++. This is because a copy of the address is given to the function (remember, the parameter is still passed by value), and that address points to the same object instance that the original pointer does. The reason you don't see any explicit pointer dereferencing within the function (similar to the C++ reference) is because Objective-C syntax for object access always implicitly dereferences -- being within a function doesn't change this behavior.

Upvotes: 0

Konstantin
Konstantin

Reputation: 861

All objects in Objective C passed by reference. All C types such as NSUInteger, double etc. passed by value

Upvotes: 0

Related Questions