What conventions are people here following for naming of instance variables and method arguments - particularly when method arguments are used to set ivars (instance variabl
As you've noted, the Cocoa style is to use method argument names like theValue
if the argument name will conflict with an instance variable. There shouldn't be many times that this comes up in Objective-C 2.0 style code, however. The assumption is that you shouldn't (usually) be accessing instance variables directly. Mostly this is because doing so circumvents the Key-Value Observing machinery in Cocoa. Rather, the expectation is that you'll access and mutate properties via getter/setter methods. In Objective-C 2.0, it's easy to declare these properties and automatically @synthesize
the getters/setters, so there's not much excuse for not using them. In fact, on 64-bit systems, the runtime will automatically create the instance variables for you, obviating the need to declare them and reducing the urge to use them.
The only time you should be accessing instance variables directly is in -init
and -dealloc
methods:
@interface MyObject : NSObject
{
id ivar;
}
@property (retain,readwrite) id ivar; //or whatever retain/copy/assign and read/readwrite makes sense
@end
@implementation MyObject
@synthesize ivar;
- (id)initWithIvar:(id)theIvar {
if(self = [super init]) {
ivar = theIvar;
}
return self;
}
- (void)dealloc {
[ivar release];
}
The reason the ivar should be used directly in these cases is beacuse the getter/setter may have side effects that depend on a fully initialized instance, thus making them dangerous in -init
and -dealloc
where the state of the object is fully initialized. In all other cases, you should be using self.ivar
(or [self ivar]
and [self setIvar:newValue]
).
It would seem that methods other than -initWithXX
shouldn't have the naming conflict. If they do, shouldn't they be refactored to not have that parameter or for the Class to not have the instance variable?
This leaves just the -initWithXX
methods where you would often find a conflict between arguments and ivars. For this case, you can use any of the approaches you mention if you really can't stand the Cocoa style. Prefixing with _
works and is relatively common (I believe the @synthesize
'd setters and getters will automatically do the right thing in this case, but you may have to explicitly set the _ivar
as the backing).
To complete all known Objective-C styleguides here is the google version. What they do is to add an underscore after the the member varname. For instance BOOL isActive_;
.
So make a choice and stick with it. I also prefer the "_" prefix for my apps.
Obj-C does not define "style" as strictly as many other languages, this might be a good thing or rather a bad one, but it means you are on your own to find a good coding style most of the time.
You can also access variables in Obj-C via self. So if you have an instance variable test, you can access it via self->test, this is legit and will always work. It's not beautiful in the eyes of most Obj-C programmers, though. It gives away the "secret", that objects are in fact just structs (more precisely, object refs are pointers to structs) and instance vars are in fact struct members. Not that this is really secret, but Obj-C programmers seems to prefer to "hide" this fact in their code.
Using underscore "_" in the name is a very bad idea. Someone here pointed out that Apple reserves underscore for their code, but actually GCC already reserves underscore for symbol names. More precisely, already the ANSI-C standard says that variables starting with either two underscores or one underscore and an upper case letter are reserved for the compiler's internal usage. So using one underscore is in theory valid, but accidentally start the name with an upper case letter and it becomes invalid.
What I tried so far was using the prefix my, myName instead of name, and using the prefix self, selfName instead of name; looks both somehow strange at first, but doesn't look too bad in a huge piece of code. At least immediately hits the eye as being "different". I also just tried a single "i", iName instead of name (or iname instead of name), but I was not very satisfied with that solution.
I never wasted time thinking about method parameters, though. Because it does not really matter. Those are variables like any other variables, unless they are declared constant. They can be even re-used for other purposes within the method, because it will have no affect on the caller. E.g.
- (NSImage *)loadImage:(int)imageNumber
{
NSImage * res;
// Some code that assigns a value to res
// ...
// Re-use imageNumber for a different purpose
for (imageNumber = 0; ...; ...) {
// Some code
}
return res;
}
I see no problem with that code. Why would I have to declare a second stack variable for that as long as the name still makes sense (if I'm not iterating over images by number in the for loop, the name makes no sense of course, in that case I would use a different variable for it - compiler may in fact reserve only one int on stack for both).
Here's how Apple does it.
The sample code produced by Apple usually uses a "_" prefix. I think I also saw some using mFoo
or m_foo
. Some don't bother with prefixes at all and just use a normal name, however that gets confusing later on. In general when defining method parameters, the naming convention is to use an "a", "an", "the" or "new" prefix. For instance:
@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
I find that this convention works quite well. I used to not bother with the prefix but that made things confusing sometimes. Using a prefix clearly indicates that it's an instance variable. The @synthesize bar = _bar
convention is used by Apple in their (iPhone) sample code.
The instance variable would not typically be used anyway, so if you find the "_" prefix annoying it doesn't matter, because you'd use [self bar]
(or self.bar
if you're into that kind of thing) anyway.