3

I have a problem accessing a IBOutlet.

I have a NIB inside which there is a tableview, a toolbar and an UILabel (encapsulated into a view). The controller (that is the file's owner) is defined as:

@interface ChoixPeriodeController : UIViewController <UITableViewDelegate> { 
 IBOutlet UILabel* __periodeInitialeLabel;
}

@property(nonatomic, retain) UILabel* periodeInitialeLabel;

- (void) setSelectedPeriode:(Tache_TypePeriode)typePeriode;

with @synthetize periodeInitialeLabel = __periodeInitialeLabel;

In the .m file, this function is called by the parent window to init the Label :

- (void) setSelectedPeriode:(Tache_TypePeriode)typePeriode {
 NSMutableString* tmpString = [NSMutableString string];

 [tmpString appendFormat:some text format....];

 self.periodeInitialeLabel.text = tmpString;
}

Into this function, I can see that self.periodeInitialeLabel is at nil. I can't see why. Everything is connected into IB... Do you see what can be the problem?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Oliver
  • 23,072
  • 33
  • 138
  • 230
  • 2
    Set a breakpoint on viewDidLoad -- which is being called first? viewDidLoad or setSelectedPeriode? – makdad Jan 15 '11 at 12:46
  • @phooze : OK... It's setSelectedPeriode.... I will have to deal with one more class attribute :-) Or do you have another solution ? – Oliver Jan 15 '11 at 12:49
  • 1
    @Joe Blow: can you not use all caps with French? What the world needs from you is AMAZING, INCREDIBLY AWESOME FRENCH STUFF!!!!! – MusiGenesis Jan 15 '11 at 12:53
  • @Joe: Marvin Hamlisch? Can I make some alternative recommendations? – MusiGenesis Jan 15 '11 at 13:02
  • @Joe Blow : the first underscores are here to prevent unwanted access from the code. When I'm tired, it prevents some minutes of searching unwanted direct calls to the attribute. – Oliver Jan 15 '11 at 13:05
  • Try Shpongle and/or Banco de Gaia. – MusiGenesis Jan 15 '11 at 13:15
  • @Joe Blow : Yes. doing this, I know exactly when I access the property or its setter. – Oliver Jan 15 '11 at 14:54
  • @phooze : could you post your comment as a solution, to make me able to accept it ? – Oliver Jan 15 '11 at 14:57

4 Answers4

5

The question here is the order of operations. If the text label is still nil, it's likely it hasn't been set up yet. Instead, you can call this method inside of the UIViewController method viewDidLoad to handle operations like this that must do "extra configuration" that couldn't be done in Interface Builder.

There is also awakeFromNib. They are very similar, except that awakeFromNib is called ONCE when the NIB file is unpackaged. viewDidLoad can be called many times - for example, if there is a low memory situation (often happens on iOS4), your views will be purged via viewDidUnload.

makdad
  • 6,402
  • 3
  • 31
  • 56
4

For anyone still having trouble with this, I was facing something similar even in a sample app. The answer turned out to be this:

UIImageView Created In Interface Builder Set To nil When Needed

[self memberVar]

Loads the property, while:

self.memberVar

Just accesses the current value, which will remain nil. So I'm trying to get away from using the "." operator. This is a very subtle issue that I've seen in a lot of sample code lately. The underscore method in the newer examples:

@synthesize memberVar = _memberVar;

still just leaves the member variable nil until you access it with [self memberVar]. I think Apple may be trying to avoid the issue by referring to _memberVar in the implementation ( for example in dealloc with [_imageView release] )


UPDATE: Also, if you are using initWithNibName or loadNibNamed to load a controller from a nib or xib on the fly (for example a custom UITableViewCell), don't forget to call:

[self loadView];

This also loads the member variables. They aren't loaded automatically unless the view is shown or does pushViewController onto a navigationController.

Community
  • 1
  • 1
Zack Morris
  • 4,727
  • 2
  • 55
  • 83
0

I think your property has to be defined with IBOutlet as well, like:

@property(nonatomic, retain) IBOutlet UILabel* periodeInitialeLabel; 

and you need to @synthesize the property in your implementation file, and then make sure periodeInitialeLabel is wired up correctly in IB (i.e. not `__periodeInitialeLabel');

Update:

If your synthesize statement looks like this:

@synthesize periodeInitialeLabel;

then that's probably your problem. I think it has to be this:

@synthesize periodeInitialeLabel = __periodeInitialeLabel;

to hook it up to your field.

MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
  • Hey MusicGenesis -- shouldn't you be off making AMAZING MUSIC like we discussed in that other post? :) – Fattie Jan 15 '11 at 12:53
  • Hey, it's Saturday. Can I not have one day off a week? – MusiGenesis Jan 15 '11 at 12:54
  • @Joe: only "fairly certain"? :-) I dunno - I stopped using IB entirely, and I'm much happier now. – MusiGenesis Jan 15 '11 at 13:00
  • @Joe: does Corona and things like it generally work? Some former coworkers of mine are using some sort of cross-platform thingamajigger to create iPhone apps that suck, but I don't know whether it's because they suck or because their framework sucks. – MusiGenesis Jan 15 '11 at 13:17
  • 1
    HEY JOE!!! IS YOUR MOUSE NOT WORKING??? CAN'T FIND THE UP ARROW NEXT TO MY ANSWER??? – MusiGenesis Jan 15 '11 at 13:23
0

Given this interface:

@interface ChoixPeriodeController : UIViewController <UITableViewDelegate> {    
    UILabel* __periodeInitialeLabel;
}

// I think it's more appropriate to mark a property with IBOutlet,
// rather than an ivar
@property(nonatomic, retain) IBOutlet UILabel* periodeInitialeLabel;

- (void) setSelectedPeriode:(Tache_TypePeriode)typePeriode;

// ...

@end

its implementation should look like this:

@implementation ChoixPeriodeController

@synthesize
periodeInitialeLabel = __periodeInitialeLabel;

// the rest of your implementation goes here
// ...

@end

I would also suggest you to look at the Google Objective-C Style Guide. Naming your ivars with two leading underscores may not be the best choice.

Alexei Sholik
  • 7,287
  • 2
  • 31
  • 41
  • Thank you. As it seems to have no side effect, I prefer to tag the ivar as IBOutlet to let me see which attributes are important in the code, and which one are not. Talking about the underscore, I'll deal with my method. Putting the underscore at the end won't prevent anything because of autocompletion that can make me do mistakes. – Oliver Jan 15 '11 at 15:00