serget
serget

Reputation: 504

XCode 4.5.2 error Unused variable when using property

I've declared the property:

@property (weak, nonatomic) IBOutlet UILabel *statusLabel;

and then I use it like this: statusLabel.text = plainText; or [statusLabel setText plainText];

In both cases I get compiler error "Use of undeclared identifier 'statusLabel'; did you mean _statusLabel?"". Actually, when I replace statusLabel with _statusLabel, compiler is happy.

I'm completely puzzled. 1. Yes, XCode automatically synthesizes _statusLabel, but I'm trying to use property, not an instance variable. Why property is not visible?

  1. Using .(dot) with ivar is wrong as I understand, dot is for properties. Why again?

  2. If I manually specify to synthesize a var without underscore, the code works, but again, it means compiler works with variable and not with property.

So, this combination works: @synthesize statusLabel = statusLabel; ... [statusLabel setText: plainText];

and this not: @synthesize statusLabel = _statusLabel; ... [statusLabel setText: plainText];

Anybody to explain? Thanks a lot. Serge

Upvotes: 0

Views: 387

Answers (4)

serget
serget

Reputation: 504

Thanks for the explanations, as I understand now, these are the valid ways to access (first 3 are for property, last 2 - directly ivar):

[[self statusLabel] setText:plainText]; 
[self.statusLabel setText: plainText]; 
self.statusLabel.text = plainText; 

[_statusLabel setText:plainText]; 
_statusLabel.text = plainText;

Upvotes: 0

Peter Segerblom
Peter Segerblom

Reputation: 2813

@property (weak, nonatomic) IBOutlet UILabel *statusLabel;

Will generate a setter named setStatusLabel and a getter statusLabel and a _statusLabel. There will be no variable named statusLabel, When you use self and "." syntax you are really calling the setter/getter and not accessing the variable directly. If you for instance need to override the setter of your property you need to use the variable directly so you don't create a infinitive recursive loop.

// NOTE: WRONG! recursive infinitive loop
- (void)setStatusLabel:(UILabel *)label
{
    self.statusLabel = label;
}

// RIGHT way (in regards to avoiding infinitive recursion)
- (void)setStatusLabel:(UILabel *)label
{
    _statusLabel = label;
}

self.statusLabel = @"";
[self setStatusLabel:[[UILabel alloc] init]];
_statusLabel = [[UILabel alloc] init];
UILabel *label = self.statusLabel;
UILabel *label = [self statusLabel];
UILabel *label = _statusLabel;

You can override the variable name if you decide to syntersize you property:

@syntersize statusLabel = myVarName;

And you can override the setter/getter name like this:

@property (nonatomic, weak, setter = mySetter, get = myGet) IBOutlet UILabel *statusLabel;

Also if you decide to syntersize the property like this: @syntersize statusLabel; the generated variable will be without "_".

Although i see no real reason for changing the default names of either the setter/getter or variable name...

Upvotes: 1

Nick
Nick

Reputation: 2369

if you allow xcode to auto-synthesize the property, then you'll need to refer to it as self.statuslabel.

Upvotes: 0

Lefteris
Lefteris

Reputation: 14677

If you don't synthesize a variable, you can only access it only through it's automatically synthesized _variable property or self.variable.

Else you can synthesize it.

It's not wrong to use it as _statusLabel. It's just fine. You can also use self.statusLabel instead of _statusLabel

You can read what @synthesize does here

Upvotes: 1

Related Questions