views:

350

answers:

3

Hello, 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];
    }
    else{
        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

+2  A: 

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?

Jared P
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
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
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
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 P
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 P
A: 

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.

kubi
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 P
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
A: 

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.

JeremyP