Related
Working on iPhone, after a lot of headache and memory problems I just realized from other examples that we do not need to necessarly create #properties for each instance variable we define in header file. And actually I found out ivars easy to just allocate and release it after I use anywhere in the class, for #properties I have to use autorealese or I have serious problems and becareful how I allocate..
For instance for objects below, #properties(retain/copy..) is not used in headers in many examples;
{
NSURLConnection *connection;
NSMutableData *xmlData;
NsMutableString *string
}
But for some strings or object types #properties is used, I know that when we set #property cocoa creates some setters getters which are handling the relasing and retaining of the objects. But seems like as for xmlData or connection instance variables we do not need that and they do their job like this.
Are there some reference guidelines I can keep in mind on deciding whether or not to create #property's or just use simple ivars?
My only problem when using properties is not becuase I am lazy to define it, but when I carefully allocate and init them in code, I have to use autorelase and dont feel like I have the control when to release reset and allocate it again, and it gives me one more thing to worry about while and when and how should I release, reset it. I find ivars I can alloc and release anytime once anywhere easily without worrying about anything..or I am missing other things here.
Tnx
There seem to still be some misconceptions flying around about properties.
that we do not need to necessarly create #properties for each instance variable we define in header file
Correct. You can use private instance variables directly in your implementation file. However, since synthesized properties come with free memory management, you might as well take advantage. My rule of thumb is to use the ivar directly until the first time I find myself writing:
[ivar release];
ivar = [newIvar retain];
As Sam says, there is already a potential bug there if iVar == newIVar. This is the point at which I switch from using ivars directly to creating a property. However, I put the declaration of the new property in a class extension in the implementation file. This means that the property is officially not part of the public interface (and will cause compiler warnings if used accidentally).
when we set #property cocoa creates some setters getters which are handling the relasing and retaining of the objects.
Actually, no. The #property just declares a property. In order to automatically generate the getter and setter, you need to #synthesize it. You could, alternatively write your own getters and setter which do not even have to reference a real ivar.
Technically, you should not use the property in the init or dealloc methods because a subclass might have overridden them or (in dealloc) you might set off a KVO notification.
From Sam's answer and comments
If you want a property regardless, you could use a private interface at the top of the implementation file
As I say above, private categories have sort of been obsoleted by class extensions (which is near enough the same thing but allows you to put the implementation of the methods in the main class implementation).
If you want the benefits of using dot notation shorthand
Some of us would argue that there are no benefits to dot notation. It's a gratuitous and needless pollution of the struct member syntax. However, dot notation has no relation to #property declarations. You can use dot notation for any accessors no matter how they were declared, provided they adhere to the pattern -foo and and -setFoo:
Create properties only for variables that need to be accessed from outside the class. Any class variables that are used internally need not have getters/setters defined.
Generally speaking an abundance of properties indicates high coupling and poor encapsulation. You should restrict what variables your class exposes in the interface.
EDITED to respond to comment:
Using properties over direct access may be preferred because it gives you easy memory management.. for example:
// interface
#property (retain) Object *someVar;
// implementation
self.someVar = otherVar;
is the same as
// implementation
if (_someVar != othervar)
{
[_someVar release]
_someVar = [otherVar retain];
}
However you should not needlessly expose vars in your interface because it opens the class up for people to use in the wrong way.
If you want a property regardless, you could use a private interface at the top of the implementation file
#interface TheClass(Private)
// private stuff
#end
First of all, let me say that Sam's answer is complete, IMO, and gives you clear guidelines (+1 from me).
My only problem when using properties is not becuase I am lazy to define it, but when I carefully allocate and init them in code, I have to use autorelase and dont feel like I have the control when to release reset and allocate it again, and it gives me one more thing to worry about while and when and how should I release, reset it. I find ivars I can alloc and release anytime once anywhere easily without worrying about anything..or I am missing other things here.
You should not worry about autorelease in the following idiom:
self.stringProperty = [[[NSString alloc] initWith...] autorelease];
because this is the way that things are meant to work;
EDIT: [the above statement has several parts:
the object is allocated and initialized (retain count is 1);
immediately, the allocated object is also autoreleased; this means that the object will be released automatically, (more or less) when the control flow gets back to the main loop;
in the very same statement, the allocated object is assigned to a retained property, self.stringProperty; this has the effect of (once again) incrementing the retain count;
So, it is true that autorelease adds some "ambiguity", because the object will be released at a time that you don't know precisely (but pretty soon anyway), but assigning to the retain property will increase the retain count so that you have full control over the lifetime of the object.]
If you don't like the autorelease you can always use a constructor method which gives you back an autoreleased object, when available:
self.stringProperty = [NSString stringWith...];
or assign directly to the ivar:
stringProperty = [[[NSString alloc] initWith...] autorelease];
because by accessing directly the ivar you are bypassing the setter and getter. Anyway, do the it only in this case (IMHO) to avoid ambiguities.
More in general, the autorelease glitch is the only drawback that using properties has over directly accessing the ivars. The rest are, IMO, only advantages that in many cases will save your life, and if not your life, a leak or a crash.
There is nothing you cannot do with directly accessing the ivars and taking care of when it is necessary to release before assigning, or not forgetting to set to nil after releasing, etc., but properties will do that easier for you, so my suggestion is simply use them and accept the autorelease shortcoming. It's only a matter of getting the basic "idioms" right.
It has long been custom to access ivars directly. That is, IMO, fine from inside the same class, although many properties are classes and then properties provide protection against retain/release issues.
IMO, it is, however, preferrable to encapsulate most ivars into properties, especially those that have retain/release semantics, but also those that need special handling, i.e. for which you write your own handlers, instead of using the synthesized ones. That way you can filter access to certain ivars, or even create properties that don't have any backing storage, and are just "aliases" to other properties, e.g. an Angle class that has a degrees property giving the angle in degrees, and a radians property denoting the same angle in radians (this is a simple conversion), or a property that must do a dictionary search to find its value, etc.
In Delphi, which was (AFAICT) one of the first languages with properties as language construct at all, it is customary to wrap ALL ivars in properties (but not all have to be public), and there are many such "unreal" (I am deliberately avoiding the term "virtual" here) properties, i.e. the ones that are only implemented in code, and not just getters and setters for an ivar.
Properties provide encapsulation, abstraction and a degree of protection against certain often made errors, and that is why they are to be preferred over direct access to ivars, IMO.
Addition
It doesn't make sense to declare and implement (either via #synthesize or with custom setters and getters) public properties for each ivar. Only expose publicly what others may need. Internal state can also be exposed to your own code via properties, but that should be done with a private or empty category in the implementation file. That way you get the automatic handling of retain/release and still don't expose them to the public.
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.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What describes #property(…) best? What's that actually good for?
If I declare a variable in my class interface, I can use such variable anywhere on my class. Awesome.
If I use #property (retain) Something *myVar; I can access that variable with self.myVar... But, what is the difference? Is there a good reason I should use one method or another?
Short answer: Encapsulation of memory management.
Longer answer: You need to establish ownership of an object if you want to use it later. If you want to use it later, you'll need a reference to it with which to do so, and a great place to keep that reference is in an instance variable.
You could handle the ownership claims (i.e. retains and releases) each time you assign a new value to that, but that would leave a lot of repetitious and trouble-prone boilerplate code scattered all over the place, like cherries in a fruitcake. That kind of mess is fiendishly difficult to debug when (not if) something goes wrong. So, it's far better to wrap that code up in accessor methods, so you can write it once and then forget about it.
But accessor methods are mostly boilerplate too, so we use #property declarations to create them automagically, rather than writing them by hand.
Edit: Apple's Memory Management Guide provides a lot of detail about what the accessor methods generated by #property do behind the scenes.
If I use #property (retain) Something *myVar; I can access that variable with self.myVar... But, what is the difference?
#property (retain) Something *myVar;
// this property declaration declares:
- (Something *)myVar;
// and
- (void)setMyIvar:(Something *)arg;
// and is accessible by dot syntax.
// it also declares and/or documents how the ivar is managed (copy, retain, etc.)
in use:
// direct access to the ivar. zero additional overhead (with regard to accessing the ivar)
[myVar message];
// properties used with dot syntax invoke the accessor. therefore,
[self.myVar message];
// is the same as:
[[self myVar] message];
the property's properties also give instructions to the compiler as to how to synthesize an accessor.
Is there a good reason I should use one method or another?
in init and dealloc, access the ivar directly - you are interested in initialization and cleanup of the object's ivars and do not care about subclasses. using properties here can also introduce bugs or undefined behavior.
for other cases, that is, when the object is in a fully constructed state, you should always use the accessor for consistency. if a subclass overrides an accessor, direct access of the ivar could break designs.
if you want to avoid this, then make the ivar private and do not declare a property for it. if you do declare a property for it, then document that it is private; i'll typically write #property (retain) Something * private_myIvar; in this case. in this case, it is convenient to use a property to synthseize the ivar's memory management.
when the ivar is private, you have total access to it. it is safe to access directly or by private property. otherwise, assume that you must use the accessor.
if myIvar is declared private and will be created only at initialization, you can avoid declaring the properties altogether. this will reduce runtime overhead (if that is critical). messaging overhead, retain/release cycles, and atomics will (naturally) require more execution time. so it can be bypassed to improve performance.
visibility/maintenance. sometimes, it's far less maintenance/implementation to hide an ivar from the interface. in other cases, the ivar is an implementation detail of the class, and should not be a part of the public interface. in such cases, consider making it private (there are a few ways to accoomplish this in objc).
Using the #property to access your ivars, does a lot of the repetitive code of releasing and retaining objects for you. You don't have to use them. It's just a lot of tutorials make it simple for people that are new to the platform.
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'm diving into iOS development and I find that for each of my UI controls, I always just blindly declare their #property like so, since that's how it was done in some tutorial I read when I started learning...
#property (retain, nonatomic) IBOutlet UILabel *lblStatus;
I'm still getting familiar with these attribute types and what they mean, but I find these two attributes allow me to accomplish my goals. Would I ever want to use any #property attributes other than "retain" and "nonatomic" for UI variables?
Thanks in advance for all your help!
NOTE: This answer is more relevant to UI Items in general.
Yes there is other situation where you would want to use the "assign" macro instead of "retain" (Assign is default for now but you get warning at compile-time if you don't specify it explicitly)
Apple gives a good example of this on one of their tutorial: Advanced UITableViewCell
They only "assign" in order to avoid cycle retains. (each of the view retains the other so they can't be deallocated).
NOTE: I missed the reference to UI variables in the question, so this answer is a more general discussion.
Yes, you will definitely need to use other attributes than those two, although that combination is the most common one.
copy - Use this in situations where you don't want as subsequent change to the data to be "picked up" by your class. In other words, when you want full control of the data once it's passed in. Sometimes this is desirable, sometimes not. Classes like NSString and UIColor are often used through properties with the copy attribute. My answer here gives a little bit more background.
assign - You use this with primitive types like int. You can't retain or copy an int or a float, because they are not objects, so you have to use assign. (Also, you don't have to, and can't, release those variables in your dealloc method.) This is true also for C structs, which are not covered by the Objective-C retain count system.
assign special case - sometimes you use assign even with objects, because you want to avoid retain cycles. Look at the header for UITableViewfor example. You'll notice that the delegate property is declared like this: #property(nonatomic, assign) id<UITableViewDelegate> delegate . Delegate properties should always be declared with assign and the same applies in some other situations, although you are not likely to run into them very soon.
nonatomic - This tells the compiler that the property is intended only to be accessed from one thread, and therefore it can omit some code that would otherwise slow down your program (potentially considerably). So the rule here is: if the property will, or might, be accessed from several threads, you should not declare it to be nonatomic (atomic is the default). Note however that making properties atomic is in no way sufficient to make your code thread safe. That's another, and much much thornier, topic.
The answer is NO. The reason behind this is the reason why we are using nonatomic and retain. From memory management guide "Objects in the nib file are created with a retain count of 1 and then autoreleased. As it rebuilds the object hierarchy, UIKit reestablishes connections between the objects using setValue:forKey:, which uses the available setter method or retains the object by default if no setter method is available. This means that (assuming you follow the pattern shown in “Outlets”) any object for which you have an outlet remains valid." So we are providing this setter just to make a match with the default behavior. Yes, it is possible to declare the setter in other ways but at least I have not found no reason to do so. If we use assign instead of retain, then there is no guarantee that the objects will remain valid. And memory management is already critical in iPhone and obviously I don't want to make it further critical by ignoring the convention. -- edit The answer NO is only for UI variables, that is for IBOutlets. Don't be confused. Other attributes are necessary in other cases as explained in other answers.
(retain) is generally used for instance variables and assign will go for delegates and primitive data types like bool , int