Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use ivars in Objective-C?

I have an application that I'm writing that uses solely @properties. I have not one ivar declared at all in any of my class files. As I understand it ivars are no longer needed with the introduction of @property. Am I coding according to best practice? Will this end up biting me in the proverbial butt in the long term? I have been reading mixed reviews on what is "right" and "wrong"...

like image 701
ElasticThoughts Avatar asked Jan 25 '12 21:01

ElasticThoughts


2 Answers

It's not so much that instance variables aren't needed. It's just that instance variable declarations aren't needed. Given a property and a @synthesize statement, the compiler will take care of creating the instance variable along with appropriate accessor methods.

There's nothing wrong with using properties exclusively. They simplify memory management. There's also nothing wrong with using iVars without properties, if that's what you want. If you want to use properties but don't want to advertise the accessors to the rest of the world (i.e. maintain encapsulation), consider declaring your non-public properties in a class extension (basically an anonymous category in your implementation file).

like image 52
Caleb Avatar answered Oct 21 '22 08:10

Caleb


I generally don't declare ivars, either. I will often use @synthesize foo = foo_; though to prevent direct access when I meant through-method or vice-versa. And I always let the compiler automatically synthesize the ivar with the _ prefix (which prevents accidental direct access, as per the struck phrase).

And, as Caleb said, there are still ivars floating about, you just don't explicitly declare 'em unless you really want to (which, really, you don't as exposed ivars in the headers are not useful to clients of the class, if your API is designed appropriately).

I also find that the hype over "only use direct access in init/dealloc, use setter/getter everywhere else" to be largely overblown and, thus, just use the setter/getter everywhere. The reality is that if you have observers during initialization/deallocation, you are already hosed; the state of the object is, by definition, undefined during construction/destruction and, thus, an observer can't possibly reason correctly about the state.


As Caleb points out, another reason to use direct ivar access in init/dealloc is to avoid subclasses that implement custom setter/getter logic that may barf due to the undefined state of the object during init/dealloc.

While this may be true, I consider it a nasty architectural flaw to implement setters/getters with custom behavior. Doing so is fragile and makes it significantly more difficult to refactor the code over time. As well, such custom behavior will often have dependency on other state within the object and that dependency then leads to order dependencies on state changes that are not at all reflected by the seeming simple @property declaration.

I.e. if your setters and getters are written such that foo.bar = bad; cannot be executed at any time on foo, then your code is busted.

like image 25
bbum Avatar answered Oct 21 '22 07:10

bbum