Why would you use an ivar?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Objective-C, an instance variable (ivar) is a variable stored directly in an object's memory layout. While properties (with @property and @synthesize) are now the standard for most use cases, ivars still have valid uses: they provide direct memory access without getter/setter overhead, they keep implementation details truly private (not visible in the header), and they are necessary in certain performance-critical or low-level scenarios. Use ivars when you need private storage without KVO, no accessor overhead, or compatibility with legacy code.
Ivars vs Properties
Property (Standard Approach)
Properties create getter and setter methods. Accessing self.name calls -name (getter) or -setName: (setter), which may involve retain/release, KVO notifications, and thread locking (atomic).
Ivar (Direct Access)
Ivars declared in the @implementation block are invisible to subclasses and external code — they are truly private.
When to Use Ivars
1. Performance-Critical Code
In tight loops processing thousands of items per frame, the overhead of property getter/setter calls (even with nonatomic) can be measurable.
2. Truly Private State
Ivars in the @implementation block do not appear in the header file. They are invisible to consumers of the class, keeping the public API clean.
3. Avoiding KVO Side Effects
Properties are automatically KVO-compliant. If you modify a property frequently during internal computation and do not want observers triggered on every change, use an ivar.
4. C Types and Structs
C structs, bitfields, and unions cannot be meaningfully wrapped in properties. Ivars are the natural choice for these types.
5. Delegate Flag Caching
This is a well-known performance pattern from Apple's UIKit source. The bitfield ivar caches respondsToSelector: results to avoid repeated message sending.
Property vs Ivar Summary
| Feature | Property | Ivar |
| Accessor methods | Yes (getter/setter) | No (direct access) |
| KVO compatible | Yes (automatic) | No |
| Memory management | Managed by setter (strong/weak/copy) | Manual in MRC, automatic in ARC |
| Visible in header | Yes (public API) | Optional (can be in .m) |
| Subclass access | Yes | Only if in header/@protected |
| Thread safety | Optional (atomic) | None built-in |
| Performance | Slight overhead | Direct memory access |
Common Pitfalls
- Forgetting memory management (MRC): Under Manual Reference Counting, assigning to an ivar does not retain the object.
_name = newNameleaks the old value and does not retain the new one. Under ARC, this is handled automatically. Always use ARC for new code. - Accessing ivars from outside the class: Ivars declared in the header with
@publicare accessible asobject->_ivar, which breaks encapsulation. Always declare ivars as@privateor put them in the@implementationblock. - Using
self->_ivarin blocks: Under ARC,_ivarinside a block implicitly capturesself, creating a potential retain cycle. Use__weak typeof(self) weakSelf = selfand accessweakSelf->_ivaror convert to a property accessed throughweakSelf.property. - Subclass cannot access implementation ivars: Ivars declared in
@implementation MyClass { ... }are invisible to subclasses. If a subclass needs access, move the ivar to the header's@protectedsection or provide a property. - Using ivars when properties are clearer: Overusing ivars reduces code clarity. Properties document the intent (strong vs weak vs copy, atomic vs nonatomic). Only use ivars when you have a specific reason — properties are the default best practice.
Summary
- Use ivars for truly private state, performance-critical paths, C structs/bitfields, and KVO avoidance
- Ivars declared in
@implementationare invisible outside the class — cleaner headers - Properties are preferred for most use cases — they provide memory management, KVO, and thread safety
- Direct ivar access (
_name) avoids getter/setter overhead, useful in tight loops - Under ARC, ivar memory management is automatic — no manual retain/release needed
- Apple's own frameworks use ivars extensively for delegate flag caching and internal state

