What kind of leaks does automatic reference counting in Objective-C not prevent or minimize?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Automatic Reference Counting (ARC) automates retain and release calls for Objective-C objects, eliminating most manual memory management bugs. However, ARC cannot detect or break retain cycles (two objects holding strong references to each other), cannot manage non-object resources (file handles, sockets, C allocations), and cannot handle Core Foundation objects without explicit bridging. These categories of leaks require manual intervention even under ARC.
Retain Cycles (The Primary ARC Weakness)
ARC increments and decrements reference counts, deallocating objects when the count reaches zero. But when two objects reference each other, neither count ever reaches zero:
Fix: Use weak for one side of the relationship:
Delegate Retain Cycles
The classic retain cycle pattern in iOS occurs when an object holds a strong reference to its delegate, and the delegate holds the object:
Fix: Always declare delegates as weak:
Block Retain Cycles
Blocks (closures) capture variables by strong reference. If an object stores a block that captures self, a cycle forms:
Fix: Use __weak to break the cycle:
The weakSelf/strongSelf dance prevents the cycle while ensuring self is alive during block execution.
Timer Retain Cycles
NSTimer retains its target, creating a cycle if the target also retains the timer:
Fix: Invalidate the timer before deallocation, or use a block-based timer (iOS 10+):
Core Foundation Objects
ARC only manages Objective-C objects (inheriting from NSObject). Core Foundation types (CFStringRef, CGImageRef, CFDictionaryRef) are not managed:
C Memory Allocations
malloc, calloc, mmap, and other C allocations are invisible to ARC:
Observer and Notification Leaks
Registering as an observer without removing creates a dangling reference (not a leak per se, but a crash or zombie access):
Thread-Related Leaks
Threads that retain objects on their stack can prevent deallocation:
Common Pitfalls
- Assuming ARC prevents all leaks: ARC only automates
retain/release. Retain cycles, CF objects, and C allocations still leak. Use Instruments (Leaks template) to find them. - Forgetting
__weakin blocks: Any block stored as a property that referencesselfcreates a cycle. Always use__weak typeof(self) weakSelf = selffor stored blocks. weakvsassign: Useweakfor object properties (zeroes out on deallocation).assignfor primitives. Usingassignfor objects creates a dangling pointer.- Bridging without transfer:
(__bridge NSString *)cfStrdoes not transfer ownership, so you still own the CF object. Use__bridge_transfer(orCFBridgingRelease) to hand ownership to ARC. - NSTimer in viewDidLoad without invalidation: The timer retains
self, preventingdeallocfrom ever being called. Withoutdealloc, the timer is never invalidated, creating a deadlock. Invalidate inviewWillDisappearor use block-based timers.
Summary
- ARC does not break retain cycles. Use
weakreferences for delegates, parent pointers, and one side of bidirectional relationships - Use
__weak/strongSelfpattern in blocks that are stored as properties - Core Foundation objects require manual
CFReleaseor__bridge_transferto ARC - C allocations (
malloc,calloc) require manualfree() - NSTimer retains its target. Invalidate timers explicitly or use block-based timers
- Use Instruments Leaks and Zombies to detect ARC-invisible memory issues
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.