Objective C - Pass by Value and Pass by Reference

Objective C - Pass by value and pass by reference

The [string lowercaseString] call creates a new NSString object that you assign to the local variable string. This does not change the value of stringVar outside the changeString function. The pointer itself is passed by value.

One way to do what you want, is to pass a pointer to a pointer:

-(void) test
{
NSString *stringVar = @"UPPER CASE STRING";
[self changeString:&stringVar];
NSLog(@"value after changed : %@", stringVar);
}

-(void) changeString:(NSString**)string
{
*string = [*string lowercaseString];
}

Passing arguments by value or by reference in objective C

Objective-C only support passing parameters by value. The problem here has probably been fixed already (Since this question is more than a year old) but I need to clarify some things regarding arguments and Objective-C.

Objective-C is a strict superset of C which means that everything C does, Obj-C does it too.

By having a quick look at Wikipedia, you can see that Function parameters are always passed by value

Objective-C is no different. What's happening here is that whenever we are passing an object to a function (In this case a UILabel *), we pass the value contained at the pointer's address.

Whatever you do, it will always be the value of what you are passing. If you want to pass the value of the reference you would have to pass it a **object (Like often seen when passing NSError).

This is the same thing with scalars, they are passed by value, hence you can modify the value of the variable you received in your method and that won't change the value of the original variable that you passed to the function.

Here's an example to ease the understanding:

- (void)parentFunction {
int i = 0;
[self modifyValueOfPassedArgument:i];
//i == 0 still!
}

- (void)modifyValueOfPassedArgument:(NSInteger)j {
//j == 0! but j is a copied variable. It is _NOT_ i
j = 23;
//j now == 23, but this hasn't changed the value of i.
}

If you wanted to be able to modify i, you would have to pass the value of the reference by doing the following:

- (void)parentFunction {
int i = 0; //Stack allocated. Kept it that way for sake of simplicity
[self modifyValueOfPassedReference:&i];
//i == 23!
}

- (void)modifyValueOfPassedReference:(NSInteger *)j {
//j == 0, and this points to i! We can modify i from here.
*j = 23;
//j now == 23, and i also == 23!
}

Is Objective-C pass-by-value or pass-by-reference?

C does not support pass-by-reference and Objective-C, being a strict superset of C doesn't either.

In C (and Objective-C) you can simulate pass-by-reference by passing a pointer, but it's important to remember that you're still technically passing a value, which happens to be a the value of a pointer.

So, in Objective-C (and C, for the matter) there is no concept of reference as intended in other languages (such as C++ or Java).

This can be confusing, so let me try to be clearer (I'll use plain C, but - again - it doesn't change in Objective-C)

void increment(int *x) {
*x++;
}

int i = 42;
increment(&i); // <--- this is NOT pass-by-reference.
// we're passing the value of a pointer to i

On the other hand in C++ we could do

void increment(int &x) {
x++;
}

int i = 41;
increment(i); // <--- this IS pass-by-reference
// doesn't compile in C (nor in Objective-C)

Are blocks passed by reference or by value from one call on stack to another?

Blocks are pointer types and the pointer is passed-by-value.

So a block created on the stack and passed to a function/method is not copied into the call frame of the callee.

However that does not mean the block may not be copied to the heap under some circumstances you may not expect when using ARC. Stack blocks are really an (internal) optimisation which due to the way they were introduced were surfaced to the user. You should not rely on blocks being on the stack.

BTW: "Copying a block" is usually just used to refer to whether the block is copied from the stack to the heap, which is not what you are asking, so you might get answers along that line.

Objective-C pass by reference vs pass by pointer. What's the difference? And why do we need it at all?]

Passing a double pointer allows the function to swap out the object you pass in. A good example is all of the many Cocoa APIs that pass a double pointer to an NSError. Take a look at this:

NSError *error = nil;
Result *result = [self someMethodWithPossibleError:&error];
if (![result isValid]) {
//handle the error
NSLog(@"Error occurred: %@", error);
}

In this case, we aren't passing an actual error instance, however since we are passing a pointer to our error, this allows them to create an NSError instance in this method, and after exiting, we will be pointing at that new instance.

Pass by value vs Pass by reference

Like Java, Objective-C has only passing and assigning by value. Also like Java, objects are always behind pointers (you never put the object itself into a variable).

When you assign or pass an object pointer, the pointer is copied and points to the same object as the original pointer. That means, if the object is mutable (i.e. it has some method that mutates its contents), then you can mutate it through one pointer and see the effects through the other one. Mutation is always achieved by calling a method, or assigning to a field directly.

-(void)testing:(NSMutableString *)str {
[str setString:@"HELP"];
}

Assigning to a pointer never mutates the object it points to; rather, it makes the pointer point to another object.

Objective-C: NSLog passing value (pass-by-reference versus pass-by-value)

Does this mean that the %@ parameter takes a pointer to the object

Yes, it takes a pointer to an Objective-C object, which can be of type NSString or any other NSObject derived type; in the latter case, the description method is used to convert the object to a string. You can think of it as the equivalent to %s for Objective-C strings.

This is how the %@ placeholder is described in Apple does:

Objective-C object, printed as the string returned by descriptionWithLocale: if available, or description otherwise. Also works with CFTypeRef objects, returning the result of the CFCopyDescription function.

Have a look at this Apple document for more details and also "String Format Specifiers".



Related Topics



Leave a reply



Submit