Take the 2-minute tour ×

I'm kind of new with objective c and I'm trying to pass an argument by reference but is behaving like it were a value. Do you know why this doesn't work?

This is the function:

- (void) checkRedColorText:(UILabel *)labelToChange {
    NSComparisonResult startLaterThanEnd = [startDate compare:endDate];
    if (startLaterThanEnd == NSOrderedDescending){
        labelToChange.textColor = [UIColor redColor];
        labelToChange.textColor = [UIColor blackColor];


And this the call:

UILabel *startHourLabel; (this is properly initialized in other part of the code)
[self checkRedColorText:startHourLabel];

Thanks for your help

share|improve this question
What do you mean by "behaving like it were a value" ? –  Ben Zotto May 23 '10 at 16:49
add comment

5 Answers

up vote 32 down vote accepted

Jared P is wrong, 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!
share|improve this answer
Yep, I solved this long time ago... :) But thanks for your answer –  Rafael Oct 9 '11 at 1:52
Technically, yes, you only pass the primitives by value. However this is entirely misleading in that while the pointer to an object is passed by value, that pointer is pointing to the same object. As there is NO OTHER WAY TO PASS (or deal with) OBJECTS, objects are always passed by reference. The only time they behave as if they're not is if OP said labelToChange = nil; or something like that, but that's something everyone here knows wouldn't work and aren't discussing. –  Jared Pochtar Oct 22 '11 at 16:49
add comment

Objective-C, like Java, only has pass-by-value. Like Java, objects are always accessed through pointers. "objects" are never values directly, hence you never assign or pass an object. You are passing an object pointer by value. But that does not seem to be the issue -- you are trying to modify the object pointed to by the pointer, which is perfectly allowed and has nothing to do with pass-by-value vs. pass-by-reference. I don't see any problem with your code.

share|improve this answer
+1 for the java comparison –  Matt Logan Nov 11 '13 at 2:24
add comment

In objective-c, there is no way to pass objects by value (unless you explicitly copy it, but that's another story). Poke around your code -- are you sure checkRedColorText: is called? What about [startDate compare:endDate], does it ever not equal NSOrderedDescending? Is labelToChange nil?

share|improve this answer
In the method, NSOrderedDescending sometimes is true as I expected. The label is no nil. Actually, if I wired labelToChange to startHourLabel it works... It seems to me that is behaving like if I were passing the label as a value and not as a reference :S .. I don't understand.. Thanks for your help! –  Rafael May 24 '10 at 7:25
What do you mean by " wired labelToChange to startHourLabel"? You can't wire a method argument to anything except by passing it as a parameter. –  JeremyP May 24 '10 at 9:49
I mean by wiring to don't use labelToChange and use the startHourLabel variable directly(just for debugging puroposes). The startHourLabel is global and it could be reach in the method. But I want to use the same method for other labels in the view. That's why I added the labelToChange parameter. Thanks! –  Rafael May 24 '10 at 17:48
gah! Global Variables == BAD. Refactor the code, then come back to this. Basically, I stand by what I said before; it is impossible to pass objects by value in objective-c; therefore this is not the problem. Far more likely it has something to do with your using of a global variable. –  Jared Pochtar May 24 '10 at 20:05
Actually, I just went back and read the problem and i think @kubi might have been partially right -- does the line 'UILabel *startHourLabel;' actually exist in the same method as the checkRedColorText: call? If so, and it is a global variable, you would be redeclaring the variable in local scope, and basically that means it ignores the previous definition. If so, it would not be pointing to the real label. If the variable is declared globally in the same file as the calling method, just leave out the line redeclaring it. If not, replace it with 'extern UILabel *startHourLabel;' –  Jared Pochtar May 24 '10 at 20:13
add comment

Did you edit out code between this line

UILabel *startHourLabel;

and this line?

[self checkRedColorText:startHourLabel];

If not, the problem is that you're re-declaring your startHourLabel variable, so you're losing any sort of initialization that was there previously. You should be getting a compiler error here.

share|improve this answer
Presumably that was for illustrative purposes, because if nothing else, there would (likely) be an EXE_BAD_ACCESS if you did anything with an uninitialized local variable. –  Jared Pochtar May 23 '10 at 16:50
Hello, thanks. No the startHourLabel is not there, the initialization is other part of the code. I declared it in the interface and I made a constructor for it. I'm not having errors there... –  Rafael May 24 '10 at 7:24
add comment

Here are the possibilities for why this doesn't work:

  1. the label you pass in to checkRedColorText is not the one you think it is.
  2. the comparison result is always coming out the same way.
  3. ... actually, there is no 3.

You claim you initialised startHourLabel elsewhere, but, if it is a label from a nib file, you should not be initialising it at all. It should be declared as an IBOutlet and connected to the label in the nib with interface builder.

If it is not a label in the nib i.e. you are deliberately creating it programmatically, you need to check the address of the label you initialise and check the address of the label passed in to checkRedColorText. Either NSLog its address at initialisation and in checkRedColorText or inspect it with the debugger.

share|improve this answer
add comment

Your Answer


