views:

144

answers:

6

Note: I know exactly what a property is. This question is about performance.

Using self.fooBar for READ access seems a waste of time for me. Unnecessary Objective-C messaging is going on. The getters typically simply pass along the ivar, so as long as it's pretty sure there will be no reasonable getter method written, I think it's perfectly fine to bypass this heavy guy.

Objective-C messaging is about 20 times slower than direct calls. So if there is some high-performance-high-frequency code with hundreds of properties in use, maybe it does help a lot to avoid unnessessary objective-c messaging?

Or am I wasting my time thinking about this?

+2  A: 

No offence, but you're probably wasting your time thinking about it. Unless you have code that accesses that property thousands of times a second, then you're not going to see any performance differences.

Jasarien
+7  A: 

This kind of premature optimization should really be postponed until you actually notice or measure (with Instruments.app) a real problem.

St3fan
good point... I can only estimate, but there are like a few thousand unnessessary property calls like this, and the iPhone is a slow thing.
dontWatchMyProfile
+2  A: 

Yes using property getters are much slower than direct access. A property getter is useful outside of the self class (and categories) for encapsulation, but I see no benefits using a self.ivar getter, unless you have overridden the getter to something else.

(And why are you using self.ivar in the first place?)

The only cases where self.ivar will be different from self->ivar are:

  1. The property is atomic, so self.ivar will be similar to

    spin_lock(&ivar_lock);
    id retval = [ivar retain];
    spin_unlock(&ivar_lock);
    return [retval autorelease];
    

    for an id property, and

    spin_lock(&ivar_lock);
    spin_lock(&destination_lock);
    memcpy(&destination, &ivar, sizeof(ivar));
    spin_unlock(&ivar_lock);
    spin_unlock(&destination_lock);
    

    for a struct. There is no difference between the two when the property is nonatomic.

  2. When the class is not final. A category of the class or a subclass can override the property getter to something else. But I think overriding a concrete property is not a good style.

Like what the others have said, unless you have tested that the getter is a hot spot, changing it back to direct ivar access won't help much.

KennyTM
If you don't use self.ivar to change the property, other objects doing key-value observation on it will not be notified of the change. Also, in the non-GC multithreaded environment, direct access of ivars is not thread safe (reading or writing).
JeremyP
@JeremyP: OP asks for a **getter**. You can KVO observe changes, but that's for a **setter**.
KennyTM
Sometimes it makes sense to use getters for internal stuff. example: you want something to happen in the case the ivar is accessed. one example: setup an object or something that must be there but is'nt right now. But in 99% of all cases getters make no sense.
dontWatchMyProfile
@kennyTM The thread safety comment applies **even for getting ivars**. also, there is the possibility that a subclass has overridden the getter.
JeremyP
@Jeremy: That's true. Updated to include these info.
KennyTM
A: 

It's a tiny bit less efficient, but you still should generally not make your object state public. Although public members are considered bad in most OO languages, there's actually a pragmatic reason why in Objective-C: The framework uses your "getter" and "setter" methods to make certain things automatic, such as memory management and KVO notifications. With ivars accessed from multiple places, every piece of client code needs to fully understand all the responsibilities that the accessor methods were taking on and perform those duties in the exact same way itself.

So it's no "absolutely don't access your own ivars," but just make sure you fully understand what it entails in a given situation.

Chuck
OP asked `self.ivar`, not `anotherObject.ivar`...
KennyTM
Makes little difference. KVO and Core Data still depend on behavior in the accessor methods, and every piece of code still has a responsibility for handling things in the original method, whether that code is in the same class or a different one.
Chuck
@Chuck: Using ivar access internally has no contradiction with `@property` / KVC / KVO / Core Data. (I did not down vote you, BTW.)
KennyTM
+2  A: 

The two aren't really interchangeable (ok some of the times they are). Access the ivar directly when that is what you need and use the accessor methods when that is what you need. It will probably depend on the the class hierarchy, the implementation of the class, is the code thread safe etc, etc.

All things that are largely upto you if it's your code. Might someone want to subclass this class and write a custom implementation of -foobar that always returned @"BOO" but they find that the superClass method -printFooBar now prints @"hello darling" because it prints out the value of the variable foobar instead of the value returned from self.foobar ?

Calling the accessor method does have more overhead than using the variable directly, but there are more things to consider than performance. Personally i find the position "always use the accessor method" just as ridiculous as saying "never use the accessor methods" - which would clearly be ridiculous.

mustISignUp
+1  A: 

Some may disagree, but I happen to like accessing the ivar directly and bypassing the whole messaging business where possible. I think it makes my intentions clearer, since if I ever need to message the getter (for memory management or the like), then I will.

David Foster
I disagree to an extent. If your ivar backs a property, you should *always* use the accessors unless performance is a real problem or in init/dealloc. The reason for this is that accessing the ivar directly bypasses the KVO mechanism and is not thread safe. Admittedly it's also not thread safe if the property is declared nonatomic.
JeremyP
and i disagree with that to an extent. No KVO mechanism is being bypassed by not using a standard getter method and you will not make your app 'threadsafe' by using atomic properties.
mustISignUp
@mustISignUp: No, even accessing the ivar to read is not thread safe without an atomic getter.
JeremyP
I know that. Im saying that using atomic getters DOES NOT give you threadsafety. You need a better scheme for that than atomically locking variable access.
mustISignUp