Take the 2-minute tour ×

I usually see this question asked the other way, such as iOS: must every iVar really be property? (and I like bbum's answer to this Q).

I use properties almost exclusively in my code. Every so often, however, I work with a contractor who has been developing on iOS for a long time and is a traditional game programmer. He writes code that declares almost no properties whatsoever and leans on ivars. I assume he does this because 1.) he's used to it since properties didn't always exist until Objective C 2.0 (Oct '07) and 2.) for the minimal performance gain of not going through a getter / setter.

While he writes code that doesn't leak, I'd still prefer him to use properties over ivars. We talked about it and he more or less sees not reason to use properties since we weren't using KVO and he's experienced with taking care of the memory issues.

My question is more... Why would you ever want to use an ivar period - experienced or not. Is there really that great of a performance difference that using an ivar would be justified?

Also as a point of clarification, I override setters and getters as needed and use the ivar that correlates with that property inside of the getter / setter. However, outside of a getter / setter or init, I always use the self.myProperty syntax.

Edit 1

I appreciate all of the good responses. One that I'd like to address that seems incorrect is that with an ivar you get encapsulation where with a property you don't. Just define the property in a class continuation. This will hide the property from outsiders. You can also declare the property readonly in the interface and redefine it as readwrite in the implementation like:

// readonly for outsiders
@property (nonatomic, copy, readonly) NSString * name;

and have in the class continuation:

// readwrite within this file
@property (nonatomic, copy) NSString * name;

To have it completely "private" only declare it in the class continuation.

share|improve this question
upvote for interesting question - well put and also one that I'd like to hear the case for ivars as it sounds like I have been taught to do it Sam's way. –  Damo Jan 31 '12 at 20:54
Note that Automatic Reference Counting (ARC) applies the same memory management benefits to ivars as properties, so in ARC code the difference is really about encapsulation. –  benzado Jan 31 '12 at 21:06
Great question. Although I've been working with iOS for some time now, I've found myself straying away from ivars since the latest obj-C standards. I don't see a need to define them explicitly anymore as they can be named in an @synthesize statement, and it's much easier to avoid retain/release problems when you use properties exclusively. N.B. Your point about defining some properties in class extensions is essential though to maintain encapsulation. –  Ell Neal Feb 1 '12 at 1:00
Your question and especially the Edit 1 part actually much more informative then the chosen answer. –  user523234 May 6 '12 at 11:54
@Sam to your Edit 1: If you use a private property and use the class extension/continuation in the .m file it is not visible for subclasses. You need to write the code again or use another .h with the class extension. Easier with @protected/default. –  Viktor Lexington May 31 at 13:37

7 Answers 7

up vote 64 down vote accepted


If the ivar is private, the other parts of the program can't get at it as easily. With a declared property, the clever people can access and mutate quite easily via the accessors.


Yes, this can make a difference in some cases. Some programs have constraints where they can not use any objc messaging in certain parts of the program (think realtime). In other cases, you may want to access it directly for speed. In other cases, it's because objc messaging acts as an optimization firewall. Finally, it can reduce your reference count operations and minimize peak memory usage (if done correctly).

Nontrivial Types

Example: If you have a C++ type, direct access is just the better approach sometimes. The type may not be copyable, or it may not be trivial to copy.


Many of your ivars are codependent. You must ensure your data integrity in multithreaded context. Thus, you may favor direct access to multiple members in critical sections. If you stick with accessors for codependent data, your locks must typically be reentrant and you will often end up making many more acquisitions (significantly more at times).

Program Correctness

Since the subclasses can override any method, you may eventually see there is a semantic difference between writing to the interface versus managing your state appropriately. Direct access for program correctness is especially common in partially constructed states -- in your initializers and in dealloc, it's best to use direct access. You may also find this common in the implementations of an accessor, a convenience constructor, copy, mutableCopy, and archiving/serialization implementations.

It's also more frequent as one moves from the everything has a public readwrite accessor mindset to one which hides its implementation details/data well. Sometimes you need to correctly step around side effects a subclass' override may introduce in order to do the right thing.

Binary Size

Declaring everything readwrite by default usually results in many accessor methods you never need, when you consider your program's execution for a moment. So it will add some fat to your program and load times as well.

Minimizes Complexity

In some cases, it's just completely unnecessary to add+type+maintain all that extra scaffolding for a simple variable such as a private bool that is written in one method and read in another.

That's not at all to say using properties or accessors is bad - each has important benefits and restrictions. Like many OO languages and approaches to design, you should also favor accessors with appropriate visibility in ObjC. There will be times you need to deviate. For that reason, I think it's often best to restrict direct accesses to the implementation which declares the ivar (e.g. declare it @private).

re Edit 1:

Most of us have memorized how to call a hidden accessor dynamically (as long as we know the name…). Meanwhile, most of us have not memorized how to properly access ivars which aren't visible (beyond KVC). The class continuation helps, but it does introduce vulnerabilities.

This workaround's obvious:

if ([obj respondsToSelector:(@selector(setName:)])
  [(id)obj setName:@"Al Paca"];

Now try it with an ivar only, and without KVC.

share|improve this answer
Good post. I like you performance, nontrivial types, and program correctness arguments. I disagree with encapsulation. Can't you define property in a class continuation to get this? I'm not as sure about threading either. Usually I'll put code in an @synchronized(...){...} block or use mutex's / locks. I may just not understand as fully as you why an ivar is better here. Binary size I'll give you, but it seems negligible. The complexity issue I think goes both ways. I think properties are both more and less complex. hehe... Maybe that makes it more complex! :D –  Sam Jan 31 '12 at 23:34
Properties vs. ivars contributes nothing to preventing other parts of an app from getting to a piece of encapsulated data. Encapsulation in Objective-C is purely compiler time enforced. Your example is specious; if that were found in code, I'd have serious words with the coder. Getting to the ivar directly is pretty trivial w/the runtime APIs (one call, IIRC). Overall, a good set of reasons, but I would emphasize that most of these are "rarely, you might want to" and don't apply in the general case. –  bbum Feb 1 '12 at 18:20
@bbum RE: Encapsulation Making the access more difficult or impossible does improve encapsulation. Making it more obvious that a dirty hack is in place can also help. Most people could write the program I posted in their first year. I also describe below how it is in fact impossible to do correctly in some cases and contexts. –  justin Feb 1 '12 at 22:50
@Krishnan avoiding accessors would be the exception. the 'overhead' is a contributor to the cost of abstraction when using objc. it's far more probable that there are other areas you can optimize to improve your apps' performance before you need to resort to using direct access as a default for IBOutlets when looking to improve your program's performance. sure, the accessors introduce some overhead, but it's very unlikely that it's a significant contributor to your program (where you are also using NIBs) because using NIBs and default UIView/NSView subtypes implies it is operating (cont) –  justin Feb 17 '13 at 7:03
(cont) at a high abstraction level -- NIB graphs don't scale particularly high. so no, i don't agree that using direct ivar accesses for IBOutlets a sensible default in a pure objc program because the biggest benefits when you need to be fast is choosing/writing the right technology/implementation for the task and then reducing the number of abstraction levels where appropriate, based on the problem you are trying to solve. so yes, they will introduce some overhead, but I would focus on several other optimizations before making the change you propose. –  justin Feb 17 '13 at 7:04

For me it is usually performance. Accessing an ivar of an object is as fast as accessing a struct member in C using a pointer to memory containing such a struct. In fact, Objective-C objects are basically C structs located in dynamically allocated memory. This is usually as fast as your code can get, not even hand optimized assembly code can be any faster than that. Accessing an ivar through a getter/setting involves an Objective-C method call, which is much slower (at least 3-4 times) than a "normal" C function call and even a normal C function call would already be multiple times slower than accessing a struct member as described above. Further, depending on the attributes of your property, the setter/getter implementation generated by the compiler may involve another C function call to the functions objc_getProperty/objc_setProperty, as these will have to retain/copy/autorelease the objects as needed and further perform spinlocking for atomic properties where necessary. This can easily get very expensive and I'm not talking about being 50% slower.

Let's try this:

CFAbsoluteTime cft;
unsigned const kRuns = 1000 * 1000 * 1000;

cft = CFAbsoluteTimeGetCurrent();
for (unsigned i = 0; i < kRuns; i++) {
    testIVar = i;
cft = CFAbsoluteTimeGetCurrent() - cft;
NSLog(@"1: %.1f picoseconds/run", (cft * 10000000000.0) / kRuns);

cft = CFAbsoluteTimeGetCurrent();
    [self setTestIVar:i];
cft = CFAbsoluteTimeGetCurrent() - cft;
NSLog(@"2: %.1f picoseconds/run", (cft * 10000000000.0) / kRuns);


1: 23.0 picoseconds/run
2: 98.4 picoseconds/run

This is 4.28 times slower and this was a non-atomic primitive int, pretty much the best case, most other cases are even worse. So if you can live with the fact that each ivar access is 4-5 times slower than it could be, using properties is fine (at least when it comes to performance), however, there are plenty of situations where such a performance drop is completely unacceptable. If your CPU drops to less than 25% performance over night, you would surly not be very happy about that.

It's similar to KVO: I remember one guy that wrote a 3D OpenGL game using Obj-C and KVO and in the end he wondered why it was so slow. Well, it turned out that only setting properties using KVO used as much CPU time as all the OpenGL, 3D and game logic code together. The app speed increased by more than 200% after all KVO coding was eliminated from the critical code paths.

Losing a cent won't make you much poorer, losing a cent a second will cost you $864 daily and losing 1000 cents a second will make most people go broke within far less than an hour. It all depends how often your getters/setters are being called (a day, a minute or a second). Since I often cannot say that in advance, e.g. when writing a framework and not being sure how other programmers are going to use this, I prefer to always go for maximum performance, unless I have a really good reason not to do so.

share|improve this answer
Extremely informative and down-to-earth explanation. Upvote for code sample –  Philip007 Oct 2 '12 at 20:32
One of the key qualifiers I see in your post is "...from the critical code paths." The point is that use what makes the code easier to read/write and then optimize what you find to be the critical paths. This will add the complexity where its needed. –  Sandy Chapman Dec 19 '13 at 18:41
@SandyChapman As with all optimizations, they'll have little effect unless done for the critical code path ;) I also never said there are no good reasons for every using properties (yet I'd dispute they make code easier to read/write; at least not anymore now that we got ARC), but that would be a different question. The question here is why one would use an ivar (instead of always using properties), and the only reason I can think of is performance. If you would like to know what I think about properties, ask the question "Why one would use a property instead of an ivar?" :) –  Mecki Jan 9 at 10:42
@Mecki Good code example :). When ARC is on, the objects will automatically be retained/released, even with ivars. Does it then also make a difference, what do you think? –  Viktor Lexington May 31 at 13:50
@ViktorLexington In my code I was setting an unsigned int which never is retained/released, whether you use ARC or not. The retain/release itself is expensive, so the difference will be less as the retain management adds a static overhead that always exists, using setter/getter or ivar directly; yet you will still save the overhead of one extra method call if you access the ivar directly. Not a big deal in most cases, unless you are doing that several thousand times a second. Apple says use getters/setters by default, unless you are in an init/dealloc method or have spot a bottleneck. –  Mecki Jun 3 at 18:05

The most important reason is the OOP concept of information hiding: If you expose everything via properties and thus make allow external objects to peek at another object's internals then you will make use of these internal and thus complicate changing the implementation.

The "minimal performance" gain can quickly sum up and then become a problem. I know from experience; I work on an app that really takes the iDevices to their limits and we thus need to avoid unnecessary method calls (of course only where reasonably possible). To aid with this goal, we're also avoiding the dot syntax since it makes it hard to see the number of method calls on first sight: for example, how many method calls does the expression self.image.size.width trigger? By contrast, you can immediately tell with [[self image] size].width.

Also, with correct ivar naming, KVO is possible without properties (IIRC, I'm not an KVO expert).

share|improve this answer
+1 Good response about "minimal performance" gain adding up and wanting to see all method calls explicitly. Using the dot syntax with properties definitely masks a lot of work that goes on in custom getters / setters (especially if that getter returns a copy of something every time its called). –  Sam Jan 31 '12 at 23:45
KVO doesn't work for me without using a setter. Changing the ivar directly doesn't call the observer that the value has changed! –  Viktor Lexington Aug 26 '13 at 15:44
KVC can access ivars. KVO cannot detect changes to ivars (and instead relies on accessors to be called). –  Nikolai Ruhe Oct 29 '13 at 17:16


  • What @property can express that ivars can't: nonatomic and copy.
  • What ivars can express that @property can't:
    • @protected: public on subclasses, private outside.
    • @package: public on frameworks on 64 bits, private outside. Same as @public on 32 bits. See Apple's 64-bit Class and Instance Variable Access Control.
    • Qualifiers. For example, arrays of strong object references: id __strong *_objs.


Short story: ivars are faster, but it doesn't matter for most uses. nonatomic properties don't use locks, but direct ivar is faster because it skips the accessors call. For details read the following email from lists.apple.com.

Subject: Re: when do you use properties vs. ivars?
From: John McCall <email@hidden>
Date: Sun, 17 Mar 2013 15:10:46 -0700

Properties affect performance in a lot of ways:

  1. As already discussed, sending a message to do a load/store is slower than just doing the load/store inline.

  2. Sending a message to do a load/store is also quite a bit more code that needs to be kept in i-cache: even if the getter/setter added zero extra instructions beyond just the load/store, there'd be a solid half-dozen extra instructions in the caller to set up the message send and handle the result.

  3. Sending a message forces an entry for that selector to be kept in the method cache, and that memory generally sticks around in d-cache. This increases launch time, increases the static memory usage of your app, and makes context switches more painful. Since the method cache is specific to the dynamic class for an object, this problem increases the more you use KVO on it.

  4. Sending a message forces all values in the function to be spilled to the stack (or kept in callee-save registers, which just means spilling at a different time).

  5. Sending a message can have arbitrary side-effects and therefore

    • forces the compiler to reset all of its assumptions about non-local memory
    • cannot be hoisted, sunk, re-ordered, coalesced, or eliminated.

  6. In ARC, the result of a message send will always get retained, either by the callee or the caller, even for +0 returns: even if the method doesn't retain/autorelease its result, the caller doesn't know that and has to try to take action to prevent the result from getting autoreleased. This can never be eliminated because message sends are not statically analyzable.

  7. In ARC, because a setter method generally takes its argument at +0, there is no way to "transfer" a retain of that object (which, as discussed above, ARC usually has) into the ivar, so the value generally has to get retain/released twice.

None of this means that they're always bad, of course — there are a lot of good reasons to use properties. Just keep in mind that, like many other language features, they're not free.


share|improve this answer

Properties expose your variables to other classes. If you just need a variable that is only relative to the class you're creating, use an instance variable. Here's a small example: the XML classes for parsing RSS and the like cycle through a bunch of delegate methods and such. It's practical to have an instance of NSMutableString to store the result of each different pass of the parse. There's no reason why an outside class would need to ever access or manipulate that string. So, you just declare it in the header or privately and access it throughout the class. Setting a property for it might only be useful to make sure there are no memory issues, using self.mutableString to invoke the getter/setters.

share|improve this answer
+1 for mention on less memory issues using properties. –  justinkoh Mar 11 '13 at 10:52

Backwards compatibility was a factor for me. I couldn't use any Objective-C 2.0 features because I was developing software and printer drivers that had to work on Mac OS X 10.3 as part of a requirement. I know your question seemed targeted around iOS, but I thought I'd still share my reasons for not using properties.

share|improve this answer

Properties vs. instance variables is a trade-off, in the end the choice comes down to the application.

Encapsulation/Information Hiding This is a Good Thing (TM) from a design perspective, narrow interfaces and minimal linkage is what makes software maintainable and understandable. It is pretty hard in Obj-C to hide anything, but instance variables declared in the implementation come as close as you'll get.

Performance While "premature optimisation" is a Bad Thing (TM), writing badly performing code just because you can is at least as bad. Its hard to argue against a method call being more expensive than a load or store, and in computational intensive code the cost soon adds up.

In a static language with properties, such as C#, calls to setters/getters can often be optimised away by the compiler. However Obj-C is dynamic and removing such calls is much harder.

Abstraction An argument against instance variables in Obj-C has traditionally been memory management. With MRC instance variables require calls to retain/release/autorelease to be spread throughout the code, properties (synthesized or not) keep the MRC code in one place - the principle of abstraction which is a Good Thing (TM). However with GC or ARC this argument goes away, so abstraction for memory management is no longer an argument against instance variables.

share|improve this answer

Your Answer


