views:

39

answers:

2

It's a question about good programming techniques with Cocoa.
When you want to call a method on one property of your class, should you use KVC to get the receiver or just put the name of your property?

Example, KVC:

[[self property] myMethod];

Example, simple:

[property myMethod];

Thanks!

A: 

I believe the formal version is technically correct as that will guarantee any side-effects from a funky getter. (To make sure, make a custom getter that includes NSLog("in getter!") and let us know if it works.)

For setting you have to use the [self setProperty:foo]; as property = foo bypasses the setter and can lead to memory leaks.

If it feels more natural to you, the dot notation (e.g., self.property and self.property = foo) is identical to [self property] and [self setProperty:foo].

John Franklin
+3  A: 

Example, KVC:

[[self property] myMethod];

That isn't KVC. The KVC way is:

[[self valueForKey:@"myProperty"] myMethod]

There is no reason to do this when you know the property at compile time; you can just ask for the property value or the ivar value directly. With KVO and (on the Mac) Bindings already implemented, there's not much reason to use KVC directly, as KVO and Bindings use it for you.

Example, simple:

[property myMethod];

That doesn't access the property; it accesses the ivar.

You're only accessing the property when you send an accessor message to the property's holder (self in your examples). It doesn't matter whether you use [self property] or self.property, as they're equivalent; either one is a property message to self, with whatever side effects that implies.

That's the key difference: Hitting the accessor may cause side effects, whereas accessing the ivar directly never will.

Hence, the best practice: Use the property in all your instance methods (as you probably want the accessors' side effects), except in init methods and dealloc, where side effects would be a bad thing. (As a general rule, you should not send messages to a half-initialized or half-deallocked object. The exception is when you explicitly commented the method as being part of your init/dealloc process and therefore wrote it to be safe to use in such circumstances.)

Peter Hosey
I'm not sure Im following you…You said to use the property in the instance methods, so I should do like this: [[self property] method], apart from init and dealloc?What you mean with accessor's side effect?
Bakaburg
`self.property` and `[self property]` are equally valid (being equivalent) ways to access the property: Both send an accessor message to `self`. Saying `property` alone does not access the property at all: It accesses the instance variable directly. Accessor methods can have side effects beyond simply accessing the ivar; the most common is setters that retain or copy the new value, but getters can have side effects, too, such as lazy fetching/computation of the value (e.g., `- (Answer *) answer { if (answer == nil) { answer = [self computeAnswer]; } return answer; }`).
Peter Hosey