views:

112

answers:

6

Are there side-effects to calling a custom getter with dot notation?

I had been using a synthesized getter in Objective-C via the dot notation, i.e.

tree.fruitnumber

returned the number of fruits in tree. I had to customize the getter (for reasons not pertinent to this question). I wrote it as

-(int) fruitnumber
{
   //climb into tree and hand count fruits. Get n;
   return n;
}

Suprisingly, the dotted getter still works. Is this legit, or there is a nasty bug (which will infect all my fruits down the road (to the market?)).

+2  A: 

It doesn't matter whether you write the getter or it is synthesized, it gets called when you use the dotted notation (or the bracket notation). This is the way it is supposed to work.

progrmr
+5  A: 

Dot notation is really just syntactic-sugar for bracket notation. So both messages are the same:

int x = [self fruitNumber];
int x = self.fruitNumber;

The nice thing is, you can @synthesize your properties and the setter/getter methods will be built for you (depending on your property options, of course) but you can write your own instead and they will be used.

In the case where you are providing your own setters/getters, you can alternatively use the @dynamic propertyName line instead of @synthesize to tell the compiler these are being provided by you.

jbrennan
+1 The complier relies on naming conventions to find accessors. It looks for methods of the form `-(AttributeType) attributeName` (getter) and `-(void) setAttributeName:(AttributeType) value`. As long as you follow these naming conventions, you can use dot notation with custom accessors.
TechZen
@tec Absolutely.
jbrennan
@dynamic is not necessary if you provide the getter and setter yourself in the implementation.
JeremyP
@jer Fair enough, +1.
jbrennan
A: 

Progrmr is correct. However I'd consider putting in the @dynamic declaration to explicitly tell the compiler you are creating the getter. Here's a link to the documentation om properties. It's worth a wad if you have had a chance.

http://developer.apple.com/mac/library/iPad/index.html#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html

Derek Clarkson
+1  A: 

The dot notation is just shorthand for calling the getter or setter method. There is no difference beyond how it looks.

A common side effect used in getters is a lazy getter.

-(id) something {
  if ( nil == something ) {
    something = ...;
  }
  return something;
}

A getter does not have to be related to a specific member. It can return the result of a calculation or lookup, or pass on something from a member object.

drawnonward
+2  A: 

There's are some side effects that no one has mentioned:

  • Atomicity - if you don't declare a property as nonatomic, then (by default) it is an atomic property, which means that the value of the property will be full retrieved regardless of what other threads might be doing to mutate the property at the same time. If you have an atomic property and then override the getter or setter, you lose the atomicity (unless you implement it yourself).
  • Key-Value observation - by using the @synthesized methods, you are ensuring KVO compliance, which makes it very easy to observe values of the object as they change (and be notified of such changes). If you override the synthesized methods, you risk breaking that compliance.

So it is generally safe to override synthesized getters and setters, but there are caveats, and it is very important that you understand what they are so that if/when things break, you know why.

Dave DeLong
Can you give an example of a case where a custom setter or getter would break KVO compliance? Not that I don't believe you, I'd never thought of it before and am curious to avoid causing problems with it.
jbrennan
@jbrennan If you implement a custom setter and you want to ensure KVO compliance you need to use either automatic or manual KVO.http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/KeyValueObserving/Concepts/AutoVsManual.html#//apple_ref/doc/uid/20001844-BAJEAIEE
JeremyP
+2  A: 

You can specify a custom getter when declaring the property, i.e.:

@property (readwrite, getter=numberOfFruitsCountedByTheCustomGetter) int fruitnumber;

In your implementation, synthesize it as usual:

@synthesize fruitnumber;

Then implement the getter:

- (int) numberOfFruitsCountedByTheCustomGetter {
    return fruitnumber;
}
Alex Reynolds