This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
When do you make an underscore in front of an instance variable?
As in Objective C, instance variable are protected by default, what are your preferred way to name it?
Assume you have an variable name, the following 3 ways have their supporters.
_foo
foo_
foo
foo. I have always disdained the _foo or foo_ styles.
Apple's Coding Guidelines for Cocoa suggest you avoid an underscore prefix:
Avoid the use of the underscore
character as a prefix meaning private,
especially in methods. Apple reserves
the use of this convention. Use by
third parties could result in
name-space collisions; they might
unwittingly override an existing
private method with one of their own,
with disastrous consequences.
and since I'm not aware of any trailing underscore convention, I don't know why you shouldn't use just foo.
You are not supposed to use underscore as a prefix as per _foo - that is reserved for Apple (and keeps you from accidentally re-defining a variable you do not know about!)
I like foo_, but only if you are writing accessors. Otherwise I just use foo. However for memory uses alone, it's good practice to always use accessors and just declare the ones you do not want public in a private category in the implementation like so:
#interface MyClass ()
#property (nonatomic, retain) NSArray *myArray;
#end
#implementation
#synthesize myArray = myArray_;
#synthesize myPublicString = myPublicString_;
- (void) dealloc
{
[myArray_ release]; myArray_ = nil;
[myPublicString_ release]; myPublicString_ = nil;
}
....
#end
Since I seem to be in the minority, I'll go ahead and throw in my two cents in the interest of balance:
I like the underscore varieties. I think it makes the code semantics more readable at a glance. Sure, syntax highlighting can do that as well, but I've always preferred the IDE/theme independent approach. Once you're used to it, it's nice to have the little guy immediately set off the "directly accessing an ivar here" alarm in your head.
Obviously, this is incredibly subjective.
As an addendum, the underscore prefix is really only especially dangerous with method names, where collisions won't be immediately exposed by the compiler, but it is probably still better to go with the suffix, if you're an underscore fan.
In general terms, why would anyone name their private variables with any suffix or prefix, most of the modern day tools do a great job in colorize them differently anyway. I prefer simply foo.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there any reason to declare ivars if you're using properties exclusively in Objective-C?
ObjectiveC ivars or #property
I am new to iPhone programming (and the programming scene altogether). I have tried to study about Properties at various places and found out that they are basically the shortcut to making getter and setter methods for other classes to get access to those objects.
Now, I have seen programmers define the object in the curly braces after the #interface:UIViewController as well as in the properties after that when all the accessing will happen within that class' .m file.
Now, that superfluous (?) piece of code, is it necessary? Is this a standard? Looking forward to some intelligible opinions.
Thank you in advance.
I can interpret your question in a number of ways:
Question: Why do some programmers use properties and instance variables (the variables defined within the curly braces), and others just use properties, and other just use instance variables?
Answer: As you know, #property declarations will, when you #synthesize them, will generate the getters and setters for you. Historically, this is all that it did for you and you had to also manually declare your instance variables. Later, the compiler was improved so that if you didn't have the instance variable defined, that the #synthesize statement would generate that, too. When this was first introduced, common practice was to define both the property and the instance variables, but Apple eventually shifted their guidelines and encouraged programmers to not define instance variables, but let the compiler generate that itself from the #property and #synthesize declarations.
So, in answer to your questions: 1. defining instance variables for your properties is now superfluous; 2. it is no longer necessary; and 3. it is now standard to not explicitly declare instance variables, but rather to let the #synthesize statement do that.
As an aside, the convention on the #synthesize statement is to, with an property called var, to precede the instance variable name with an underscore, thus #synthesize var = _var. This is done to minimize the chance that a programmer might accidentally refer to an ivar when the property was intended (or vice versa). To further illustrate that this is the preferred standard, starting in Xcode 4.4, even the #synthesize statement is optional (thus, define the #property, but no ivar, and no #synthesize) and it will declare and ivar the same name as your property, except with a leading underscore.
Question: Why do some programmers define some of their properties and instance variables in the .m file? Why do other programmers declare some of their instance variables and properties in the .h file when they're only being used within the class's own .m file.
Answer: Those instance variables and properties defined within the .m file (in what is called a class extension) are just a convenient way of defining those ivars/properties that are not advertised to the world. In this convention, your .h file becomes just your public interface (what properties and methods can be invoked from elsewhere) and everything else goes in the .m file. It's a nice way to keep your interfaces a little cleaner so when you go to use your class at some future date, you can just look at the .h file and not get too lost in the details of the class's implementation details.
In the past, before class extensions became prevalent, we defined all of our instance variables and properties in the .h file, even if they were private and used only within the class's own .m file. Thus, you'll still see some code that does this.
So, in answer to your questions, 1. it's not superfluous to use class extensions (unless your class extension is empty, but even then I tend to keep it so I can see that there are no private ivars/properties); 2. the use of class extensions is not necessary; but 3. the use of class extensions for private properties/variables that are used only within the class itself is an emerging standard and probably does represent best practice.
This question already has answers here:
When should I use the “self” keyword?
(6 answers)
Closed 9 years ago.
I have an attendant question to iPhone: Why do I need self.<> in viewDidUnload?
Since there is a difference between using self.instance and instance, when is only instance actually used? Just setting the reference to nil seems quite useless? Why is the option there?
Generally, you'll find a lot of useful information here: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html%23//apple_ref/doc/uid/TP40004447-SW4
For the rest of this answer, I'll assume that you are referring to properties automatically synthesised with the #synthesize directive in your .m files.
Executive summary
When you use the form self.property, retain/release is automatically taken care of for you. When you use the form instanceVariable without the self prefix, you're on your own with retain/release.
Longer explanation
When you omit the "self." part, what you really are doing is that you access the automatically generated underlying ivar which the compiler has given the same name as you have given to the property.
If you don't want the compiler to generate ivars of the same name, then you can use an extended form of the #synthesize directive, like this:
#synthesize myvariable=__myvariable;
That way, you will ask the compiler to create an underlying ivar called __myvariable instead of the default myvariable.
Using this extended form, you would refer to either self.myvariable (as a property) or __myvariable (as an instance variable), which can be handy to visually distinguish the two types of access.
With that in place, we can get to the substance of the matter.
When you use self.myvariable, you implicitly call the accessor methods (possibly synthesised for convenience), like this:
self.myvariable = #"Some string";
is equal to
[self setMyvariable: #"Some string"];
or, in the case of a right hand use of the property
myLocalVar = self.myvariable;
is equal to:
myLocalVar = [self myvariable];
The examples above use the accessor names recommended by Apple.
On the other hand, when you use the instance variable directly, you just assign the variables directly without going through the accessors.
Now, one huge advantage of using the accessors on the iPhone is that the automatically synthesised accessors also take care of the retain/release messages, so you don't have to worry about that - or waste code lines handling this somewhat tedious stuff.
Since there is no need to worry about retain/release when you are just reading a property, you could argue that you only need to use the property syntax (with self.) on the left side of an assignment, so whether you want to use the self.-syntax on the right hand side of an assignment is partly a matter of style.
Personally, I have developed a style where I try not to refer to automatically synthesised ivars, unless I have specified them in the #synthesize directive. Otherwise Apple might one day change the way an unspecified #synthesize directive works, and my builds would break. But that is just a personal precaution of mine.
There is one exception to all this, as stated in the docs linked at the top of this answer - and that is that you should not use accessors to the class' own instance variables in the init* methods. One the Mac, you shouldn't use them in the dealloc methods, either, but this is one point where Apple's coding recommendations differ between the two platforms.
Ok, this was a long answer to just say, read the docs, but I hope it clarifies things a little. Memory management in reference counted environments is not trivial, so don't despair if it isn't clear at first.
PS: And if you think this the sort of worries that others should solve for you, log a bug with Apple to ask for garbage collection on iOS. It works nicely on 64-bit OS X.
aclass.h
#interface aClass : NSObject {
NSString *name;
}
#property (nonatomic, retain) IBOutlet NSString *name;
#end
aclass.m
#implementation aClass
#synthesize name;
- (void)dealloc {
[name release];
[super dealloc];
}
- (void)test1 {
name = #"hello";
}
- (void)test2 {
self.name = #"hello";
}
Take above as an example. Could someone please explain the difference between name = #"hello" and self.name = #"hello"? Thanks!
EDIT: Follow-up question: How to write my own setter for an ivar, i.e.: self.ivar = ...?
BE AWARE, THIS POST IS OLD !
This post is from the previous decade.
Be sure to read the important footnote down below, cheers!!
It's really difficult to understand all this, when you're just getting started.
Here are some SIMPLE, PRACTICAL rules of thumb FOR BEGINNERS.
To repeat, this post is FOR BEGINNERS.
The aim here is to allow you to quickly move from the starting line, to being able to confidently use the system in most situations.
Later, you can really learn about the inner workings of these issues.
(1) Don't ever say name=#"hello". Always say self.name=#"hello". Do a project-wide search for name and ensure you always say self.name and not name, when you set it or change it.
(2) You know all that infuriating stuff about memory management, initialising, releasing and so on. If you use the self thingy, it takes care of all that for you. Cool huh?
(3) The self thingy is particularly useful because you can easily "change" the string (or whatever it is) as you go along. So, it's totally OK to do this,
self.name=#"aa";
self.name=#"bb";
self.name=#"cc";
whereas (in a word) you can never, ever, for any reason, do this...
name=#"aa";
name=#"bb";
name=#"cc";
( * ) Regarding your literal question, "please explain the difference between name = #"hello" and self.name = #"hello"?" This is easy to do.
The first one is just setting a variable. You know, exactly like "x=42" in the old days when life was simple and we were 13 years old.
The second one is completely different, specifically it is calling a complicated routine (known as "the setter") to do a whole lot of amazing and astonishing stuff for you.
So that is the literal answer to your question. The first one just sets the variable (and don't forget, there are a whole lot of pointers and other weird stuff involved, and as a rule you certainly can not just set pointers willy-nilly like that). The second one actually calls a big complicated routine and hence does a whole lot of stuff for you.
Once again, the second one is exactly like saying...
[name bigComplicatedRoutineHere:#"hello"];
...it is very helpful to always remember that the syntax self. ... is literally calling a routine.
Indeed, some thinkers on the topic thought it was a dumb idea when they introduced this self.X syntax to mean [X complicatedThingHere]. It introudces a lot of confusion, and every beginner asks exactly what you are asking.
Personally, it took me over nine years to get this clear in my head. :-) So again, I emphasise that you must remember that when you say self.x, in fact, you are actually calling a routine.
To repeat: the "self dot" syntax in fact calls a routine. (Indeed I believe one of the preprocessors simply expands it to [x amazingStuffHere]. )
I have tried to answer in a way that will keep you going and allow you to advance and use more features, while you learn about memory management, properties, and so on. If you are more advanced than this post, just ignore it.
Please note that this post is meant to be advice for beginners to enable them to keep going and not get infuriated. Hope it helps!
2014 update! Important Note on ARC for beginners ...
Note, this post is five years old now! It's been read by thousands of beginners and there have been many followup questions etc. Please note that, today in the new "ARC world". To some extent: if you're a beginner: you should pretty much only use!! properties. ie, use "self.whatever" at all times, everywhere. In any event, just be aware that the information in this post is "largely historic" and is becoming more so every day. Of course, it goes without saying that once you are an expert, you will need to and will understand every subtle detail of all this. Hope it helps someone.
self.name uses the accessor and/or mutator defined by you (this is nonatomic and retain in your case). So when you call self.name = foo, it will call the setName:(NSString *)str mutator generated by the compiler, which will first release the current string, then retains the new string and finally sets name to the retained string.
Just calling name = foo does nothing more than assigning name to foo.
This also means that you can only call self.xxx when you have defined a property for the ivar, otherwise the compiler will tell you that it doesn't know about it(iVar).
name = #"Joe"
You're accessing directly the variable, bypassing the getter method that Cocoa took the trouble of creating for you. Usually, not the wisest thing to do.
self.name = #"Joe"
Now your going through the method you asked cocoa to create for you. This is usually the best way.
As a rule of thumb, use always the setter and getter provided by Cocoa, with ONE exception: dealloc. In dealloc, you should always release the variable directly, not through the getter method:
-(void) dealloc {
[name release]; // instead of [[self name] release]
...
[super dealloc];
}
The reason to avoid accessors in dealloc is that if there are observers or an override in a subclass that triggers behavior, it'll be triggered from dealloc which is pretty much never what you want (because the state of the object will be inconsistent).
OTOH, there's also a slightly more convenient syntax for declaring iVars that you might not be aware of. If you are only targeting 64bit macs, You can use properties to generate both accessor methods and the instance variable itself:
#import <Cocoa/Cocoa.h>
#interface Photo : NSObject
#property (retain) NSString* caption;
#property (retain) NSString* photographer;
#end
It's real a memory management, firt the property grammar is real setter and getter method, when use self.xxx = ?, it could call setter method, the object retain cout +1, name can not be release, however if name = foo is nothing about property grammar.
setter method example:
-(void)setObj:(ClassX*) value
{
if (obj != value)
{
[obj release];
obj = [value retain];
}
}
I noticed a difference between the way I code (badly ;) ) and the code I see from others.
Can anybody explain why I see some people using
self.varname.anotherpropertie
When
varname.anotherpropertie
Seems to work just as well. I dont use self. a lot in my code. I'm wondering is this very bad or is there something that I need to learn to understand why its used so much by most people?
Thanks again,
-Code
They are different things. In a class where you have an instance variable named foo with a declared property also named foo, writing simply foo accesses the instance variable while self.foo goes through the getter method for the property (which might just return the instance variable or it might do more).
I'd suggest taking a look at the Declared Properties chapter of Apple's The Objective-C Programming Language for a full explanation of how it works and when to choose which option.
One gotcha that I've run into is the retain vs non-retain with properties.
So if you have a retained property like this:
#property (nonatomic, retain) NSString* myStr;
#synchronized myStr;
and you do something like this:
- (void) myMethod:(NSString*)inStr
{
myStr = inStr;
}
In this example you will not actually retain the string as your property is not invoked. If you change the assignment line to use the property (by using "self.") then the string would be retained (and the previous string would be released if non-nil).
self.myStr = inStr;
It takes some getting used to that properties are method calls, but once you start seeing them as such then the "self." syntax becomes much more clear. Hope that helps some.
This question already has answers here:
Closed 10 years ago.
I've previously avoided underscores in my variable names, perhaps a holdover from my college Java days. So when I define a property in Objective C this is what I naturally do.
// In the header
#interface Whatever
{
NSString *myStringProperty
}
#property (nonatomic, copy) NSString *myStringProperty;
// In the implementation
#synthesize myStringProperty;
But in almost every example it is done like
// In the header
#interface Whatever
{
NSString *_myStringProperty
}
#property (nonatomic, copy) NSString *myStringProperty;
// In the implementation
#synthesize myStringProperty = _myStringProperty;
Should I get over my aversion to the underscore because that is the one way it should be done, is there a good reason for this style being the preferred one?
Update: With automatic property synthesis nowadays you can leave out the #synthesize and the result is the same as if you'd used
#synthesize myStringProperty = _myStringProperty;
which clearly shows you Apple's preference. I've since learned to stop worrying and love the underscore.
I always use underscores. It creates a clear distinction between local variables and instance variables. It also avoids compiler warnings in the following situation:
#interface MyClass
{
NSString *name
}
#property (nonatomic, copy) NSString *name;
- (id) initWithName:(NSString *) name;
#end
#implementation MyClass
#synthesize name;
// The following method will result in a compiler warning
// (parameter name same as ivar name)
- (id) initWithName:(NSString *) name {
if (self = [super init]) {
self.name = name;
}
return self;
}
#end
EDIT:
After having to endure downvotes and reading through the comments, let me try to make my point:
Apple recommends that ivars have the same name as their property. Apple also recommends that properties start with a lowercase letter. And Apple also recommends that local variables start with a lowercase letter.
Now you have a problem, because when you read a piece of code, and you see a variable being used, you cant' tell by the naming convention if this variable is an ivar or a local variable. That sucks. The solution is to have different naming conventions for ivars and local variables. That's just plain common sense.
The way you implement this naming convention is irrelevant. If you really want, you can simply append "_WOOHAHA" to the ivar names. I don't care (but maybe others will). The thing is that people who know what they're doing have decided to go with the "underscore prefix" for ivars. IMHO, they made the right decision, even if their own company recommends something else. (the developers I'm talking about are the people writing some major Apple frameworks and the .NET Framework classes)
In the end, code quality is more important than following a stupid rule that isn't even followed by the people preaching it.
Another remark about the code you've shown: never use retain on string properties. You should use copy instead.
For more info about copy/retain on properties, see:
NSString property: copy or retain?
The naming convention for the instance variable prefixed by _ is now clearly stated by Apple in the "Coding Guidelines for Cocoa", after the revision of 2012-02-16, with its reason.
Make sure the name of the instance variable concisely describes the attribute stored. Usually, you should not access instance variables directly, instead you should use accessor methods (you do access instance variables directly in init and dealloc methods). To help to signal this, prefix instance variable names with an underscore (_), for example:
#implementation MyClass {
BOOL _showsTitle;
}
If you synthesize the instance variable using a declared property, specify the name of the instance variable in the #synthesize statement.
#implementation MyClass
#synthesize showsTitle=_showsTitle;
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284-BAJGIIJE
The lecture in iTunes U, iPhone App Development CS193p Fall 2011 taught by Paul Hegarty at Stanford University, also explains this convention.
http://itunes.apple.com/itunes-u/ipad-iphone-application-development/id473757255
I'm aware of that this question is asked quite a while ago, but I myself had the same question and wanted to share my findings.
Current suggested Objective-C 2.0 practice is to use the same name for the ivar as the property. You can optionally assign a different ivar in the #property declaration, but the fact that by default, synthesized accessors for a property will access the ivar with the same name as the property indicates that's the pattern they expect you to follow.
No matter what, since objects still have to send messages to themselves to access properties, it's hard to confuse when you're accessing a property or when you're accessing its backing ivar directly, though using the 2.0 dot access to properties does make it more possible. Using the standard message passing syntax makes intent more explicit, IMO.
#interface Foo : NSObject {
NSNumber *bar;
}
#property(readwrite, retain) NSNumber * bar
#end
#implementation Foo
#synthesize bar;
-(void) baz {
NSNumber *numberOne = [NSNumber numberWithInt: 1];
//Both set the value of bar through either the your custom or the synthesized setter method
[self setBar:numberOne];
self.bar = numberOne;
//Both get the value of bar through your synthesized or your custom accessor method
NSNumber *fooBar = [self bar];
fooBar = self.bar;
//Both manipulate the bar ivar directly
bar = numberOne;
fooBar = bar;
}
#end
Apple reserves selectors beginning with underscore for their own "private" methods and that would include properties. I don't think they reserve _ for ivar names though.
Personally, I would steer clear of using underscore to start any kind of variable name. It's an opaque convention. What if somebody else uses underscore for locals and no underscore for instance variables? What if you accidentally omit the underscore in a method where you have a local defined with the same name?
It's much better to make your local names different from your ivar names. For example in a setter you might use newName or neWValue.
It is purely a style issue.
I don't know which examples use the underscored ivar style. The official Apple examples (e.g. CryptoExercise) do not prefix the ivars with _.
I will just point out that a new navigation project using core data uses trailing underscores by default and makes the variables private.
#interface MyTestAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navigationController;
#private
NSManagedObjectContext *managedObjectContext_;
NSManagedObjectModel *managedObjectModel_;
NSPersistentStoreCoordinator *persistentStoreCoordinator_;
}
#interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate> {
#private
NSFetchedResultsController *fetchedResultsController_;
NSManagedObjectContext *managedObjectContext_;
}
The KVC part of the runtime expects either a name or _name ivar when using valueForKey: on an object when it cant find a message to retrieve that variable. see http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/SearchImplementation.html
If the runtime bothers to search for _name and the apple documentation mentions the _name first there might be a good reason for this. Let's take a look at some SDK classes: UINavigationBar.h this class has underscores in front of all ivars, UIView too... the list goes on. Well maybe it is that way with the new fangled iOS SDK and good ole NS* classes don't do thinges that way... wrong; they use the underscore as well in the header files.
Apple uses the underscore in private API messages as well as ivars. I can't understand why their examples do not push this behavior especially when the runtime bothers to have this so called "naming convention" hard coded into the variable search path. It would be nice to see some consistency.
Just a note, there is a strict naming scheme you have to follow to be KVC compliant; the link above helps you to conform to this to use this handy feature of the runtime.