views:

87

answers:

3

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!

+1  A: 

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.

taskinoor
+1  A: 

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.
Felixyz
The question was about UI variables that is about IBOutlets. Not for other variables.
taskinoor
Ah, thanks, you're right. I think I'll leave this here though as a complement to Pier-Olivier's answer.
Felixyz
Sure you should leave it as you have given a nice explanation.
taskinoor
+2  A: 

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).

Pier-Olivier Thibault
there are many cases where u need other attributes but in this case the question is specially for IBOutlets.
taskinoor
Why do you want to keep your retain count low? The retain count doesn't matter. What matters is if your retains and releases are balanced or not. (But nice reference to the UITableCell scenario. I can imagine similar scenarios when using proxy objects for example.)
Felixyz
Well he talks about UI controls. UI Controls can be build without the Interface Builder AFAIK which makes my argument still valid with the Advanced UITableViewCell exemple.
Pier-Olivier Thibault
For the retain count. Having it lower made it easier for me in the past to know what was happening when leaking. Keeping it low for me also helped avoiding leakage.
Pier-Olivier Thibault
The presence of IBOutlet in the property declaration means that it is loaded from nib. Yes, we can build any thing without IB, no doubt in that. But memory management of nib is different from other cases. You should use retain when loaded from nib.
taskinoor