views:

475

answers:

3

Objective-C 2.0 gave us @properties.

  • They allow for introspection.
  • They allow for declarative programming.
  • The @synthesize and @dynamic mechanisms relieve use from having to write repetitive, stock accessors.
  • Finally, there is the ‘dot’ property syntax, which some love, and some hate.

That isn't what I'm hear to ask. Like any new feature, there is an initially tendency to want to use @property everywhere. So where is property use appropriate?

Clearly in model objects, attributes and relationships are good fodder for properties.

@property(...) NSString *firstName;
@property(...) NSString *lastName;
@property(...) Person *parent;

Even synthesized/computed attributes seem like a good use case for properties.

@property(...) NSString *fullName;

Where else have you used properties? Where have you used them, then later decided it was an inappropriate use of the feature?

Do you use properties for your private object attributes?

Can you think of any examples of things which aren't properties in Cocoa, which at first look, seem like they might want to be properties, but after closer inspection, are actual an example of abuse or property-itis?

+5  A: 

My recommendation to people is to use property's wherever possible. If you are working in a framework, the ability to use non-fragile instance variables in the modern runtime is a huge bonus and if you aren't, properties make it clear how your ivars are to be managed (assigned vs retained vs copied). There isn't an inherent performance loss from declaring a property other than the time it takes to write the line of code (I actually use a TextExpander snippet to do this for me) but the potential for preventing bugs is large enough that it becomes a fantastic best-practice. If you do plan to user properties for private ivars, you can do so inside your implementation file via an @interface block. For example

@interface MyObject()

@property(retain) NSArray *myArray;

@end
wisequark
Another advantage of using properties whenever you can is that you get an automatic retain that setting an internal variable and having to remember to call retain...
Kendall Helmstetter Gelner
+4  A: 

If I had to think of a reason to avoid them, I'd say don't use it for computed attributes where the computation involved is significant. Properties encourage code like:

if (foobar.weight > 100) {
    goober.capacity = foobar.weight;
}

In this example, foobar.weight is called twice. If it's just returning a cached value, no problem. But if it needs to block the thread while it deploys a robot to manually weigh the foobar each time, the above snipped of code would waste two robot deployments when only one is needed.

In such cases, I'd recommend NOT using a property, and also naming the method differently, so that the code would look more like:

int w = [foobar computeWeight];
if (w > 100) {
    goober.capacity = w;
}

With a name like computeWeight it is easier to remember that it is a long running operation.

benzado
This is more of an issue that is the result of a poor design decision. The accessor should *never* cause a long computation to result and should instead return a cached value local to the object owning the property. If a long computation is to occur it should be explicit.
wisequark
“The accessor should *never* cause a long computation to result and should instead return a cached value local to the object owning the property. If a long computation is to occur it should be explicit.”Isn't that basically what he said?
Peter Hosey
If we define a property as some ivar which is exposed by means of an accessor or mutator or both, then computeWeight is not the same as getWeight and getWeight should not necessarily call computeWeight.
wisequark
A: 

I would avoid using properties if the accessor method does something non-obvious to the object, like setting an unrelated instance variable. Also if the property being returned doesn't really "belong" to the object. For instance, in one of my projects I have a stringValue method that I decided not to make a property for this reason. This is really more a matter of style though.

Marc Charbonneau