Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should I use @properties? [duplicate]

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?

like image 776
Voldemort Avatar asked Apr 09 '11 04:04

Voldemort


2 Answers

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.

like image 114
Sherm Pendley Avatar answered Sep 19 '22 00:09

Sherm Pendley


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

like image 23
justin Avatar answered Sep 21 '22 00:09

justin