3

Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?

I'm using the same convention for instance variable and properties naming as shown by sebnow in his following answer:

instance variable/ method argument naming in Objective C

I copy paste his example code here:

@interface Foo : NSObject {
    id _bar;
}
@property (nonatomic, retain) id bar;

- (id) initWithBar:(id)aBar;

@end

@implementation Foo
@synthesize bar = _bar;

- (id) initWithBar:(id)aBar {
    self = [super init];
    if(self != nil) {
        _bar = aBar;
    }
    return self;
}

@end

In the implementation of some methods of the Foo class, I use for example:

_bar = aBar

instead of using:

bar = aBar

The 'Analyse' tool introduced by Xcode 4 gives me this warning (I'm using version 4.0.2):

Instance variable 'bar' in class 'Foo' is never used by the methods in its @implementation (although it may be used by category methods)

Perhaps I should use:

self.bar = aBar

But for the readonly properties, that can't work, and beside that, I'm not sure if using the setter in the class itself is a good practice or not.

I'm not fresh in Objective-C, but I'm still in the beginning of learning. Perhaps I'm doing something wrong, and have a bad coding practice somewhere.

Thanks you in advance if you can help me ;)

Community
  • 1
  • 1
  • I'm not sure what you are asking, the static analyser is just telling you that you never access `bar`. This is correct as you example is so simple. In a more complex implementation you would use `self.bar` and the analyser will shut up. – Richard Stelling May 25 '11 at 12:09

5 Answers5

2

"Is never used" should be taken literally: you only define its value in assignments, never use it.

This is the same kind of warning you get for local variables: if you only define their values and never use it, what are they for?

The static analyzer is thus warning you, because typically variables that are never accessed are just remains of older code that has changed and you can remove them. But in your case it could be perfectly fine.

sergio
  • 68,819
  • 11
  • 102
  • 123
  • Oh... I just saw my error. Which is completely stupid. Really stupid indeed ;) My iVars where defined without the underscore after a test in my Class and things get confused with the synthesize process of my properties. – Stanislas Krasnaya May 25 '11 at 12:17
  • that was why the warning was there! it is confirmed that it is better to never disregard a warning in objective-c... glad to have helped... – sergio May 25 '11 at 12:20
  • Yes I never disregard warnings in Objective-C! :) – Stanislas Krasnaya May 25 '11 at 12:23
2

The @synthesize line affects how the setter and getter for the property 'bar' operate. The line:

@synthesize bar = _bar;

Effectively says "put in the standard getter (and setter, if relevant) for bar, as per the way I've declared it as a @property, but use the instance variable _bar for the storage".

When you use self.bar as an lvalue you're actually making a method call to [self setBar:] and when you use it as an rvalue you're actually making a call to [self bar]. It looks like a normal C-style struct member access but internally it's a method call.

So, the @synthesize creates a suitable getter and setter to use for self.bar, but doesn't change the name of the instance variable. You should therefore be right to use _bar when accessing the thing directly from within the class itself (though some people now frown upon that from a style point of view) and self.bar otherwise, without receiving any analyser warnings.

For you to end up with an instance variable called bar, assuming you didn't declare one inside your interface, the most likely mistake is an error in the way you've performed your @synthesize. In the modern runtime you can supply a @property/@synthesize pair for a variable you haven't actually declared in your interface and the variable will be magically added to your interface. So you can do that by accident if you make an unfortunate typo.

If possible, could you post your actual code?

Tommy
  • 99,986
  • 12
  • 185
  • 204
  • Thanks for the reply, and like I said on my previous reply, I made mistake, after a test of removing the underscore in front my iVars declaration. – Stanislas Krasnaya May 25 '11 at 12:24
  • But you're right. The @synthesize is very powerful, but can be very confusing. And even if I saw my error, your above answer clarify me some things in the synthesize process! I can't reply myself on my question. But my actual code wasn't like the one I paste in my question but like this: @interface Foo : NSObject { id bar; } So the Analyse warnings are now understandable. – Stanislas Krasnaya May 25 '11 at 12:32
0

Please see my comment.

Try adding a -dealloc method to release the object. This will 'access' the Ivar and should make the static analyser happy.

-(void)dealloc
{
    [bar release]; bar = nil;
    [super dealloc]
}
Richard Stelling
  • 25,607
  • 27
  • 108
  • 188
0

Now that I can respond to my question 8 hours later, I'm doing it for anyone who made the same mistake as me during some test or something. However, the answers of sergio and Tommy are very informative.

After reading answers, I saw that I made a silly mistake. During a test of coding of my class, I removed the underscore before my instance variables declaration. So my actual code was truely looking like this:

@interface Foo : NSObject {
    id bar;
}

@property (nonatomic, retain) id bar;

- (id) initWithBar:(id)aBar;

@end

@implementation Foo
@synthesize bar = _bar;

- (id) initWithBar:(id)aBar {
    self = [super init];
    if(self != nil) {
        _bar = aBar;
    }
    return self;
}

@end

So the Analyse warnings were correct. Sorry for the false alarm! But thanks for very fast answers.

-2

use this ->

@interface Foo : NSObject {
    id _bar;
}
@property (nonatomic, retain) id _bar;

- (id) initWithBar:(id)aBar;

@end

@implementation Foo
@synthesize bar = _bar;

- (id) initWithBar:(id)aBar {
    self = [super init];
    if(self != nil) {
        bar = aBar;
    }
    return self;
}

@end
iOSPawan
  • 2,884
  • 2
  • 25
  • 50