One of the key factors for the success of any application is its performance. Effective Memory Management in an application is crucial for better performance of the application. iOS applications developed using Swift language rely on ARC for tracking and managing application memory usage. ARC uses reference counting to manage the application memory.
What is ARC?
ARC is a memory management tool which tracks and manages the application memory. It is a compiler-driven feature. It observes the reference count of an object of a class to manage and free the memory. So the question is what is reference count?
Reference count in simple language is the “number of pointers to any object”.
Reference counting only applies to class instances, so struct & enum do not participate in reference counting.
How ARC Works?
As mentioned, ARC is a compiler-driven feature. It inserts retain and release statements during compilation.
- Retain - increase the reference count.
- Release - decrease the reference count.
ARC is the compiler-driven feature and it injects retain/release statements in a code during compilation time.
How does the compiler decide when to insert retain/release?
Object life cycle in Swift begins with init and ends at last use.
ARC decide based on the above when to add retain and release statement.
The object life cycle in Swift is different from the other language. In most of the other languages, it ends at the closing brace.
However, code should not be written based on this assumption as it might change with future compiler changes. For example, the following code is a good example of a team nightmare that suddenly a working code stopped.
In the above case, it is wrong to assume that goaWeakTrip will always be there. The last use of the object is weak var weakRefrenceToGoaTrip = goaTrip and the compiler will insert release after this statement.
So print statement here totally depends upon how the compiler works. if an Object’s life cycle in Swift begins with init and ends at last use. is strictly followed by the compiler then 50000 is the result. In the future, due to some drawbacks of this approach, Apple decided the scope based on the brace start and end then the result will be different.
ARC need your help.
ARC cannot detect or break **Reference cycle **. If object holds a strong reference to each other directly or indirectly in that case memory cannot be released of the objects.
In the Direct case, the Trip and TravelDiary objects are strongly held together. Therefore, releasing one object requires the release of the other object as well. We can break the reference cycle here by making reference weak in the Trip object for the TravelDiary.
In the Indirect case, the Person object is strongly held TravelDiary Object. TravelDiary strongly holds the trip object and further Trip holds the person object strongly. Therefore, releasing an Object in this scenario requires other two objects should be released. We can break the reference cycle here by keeping Person Object in the Trip object weak.
Weak & Unowned Reference Cycle
To break the reference cycle weak and unowned keywords can be used. Both reference type does not participate in reference counting.
Weak reference can be used when you are not sure about the life cycle of the referred object. It will automatically be set to nil if the object reference count becomes zero. The only constraint with weak is must be optional.
Unowned reference can be used when you are sure about the life cycle of the referred object and it will not be deallocated. It can be used with an object which has an equal or greater life cycle. Unowned references can be declared as non-optional and faster access as compared to weak ones. The weak need to unwrap to access the value.
A weak reference is automatically set to nil if no strong reference remains and a weak reference is always optional. Unowned references will refer to deallocated memory if no strong reference remains, so the application can crash. Unowned is always non-optional.
Bonus.
There are safe ways to access the weak reference to avoid unexpected results or fatal exceptions (force unwrap) at run time.
Comments powered by Disqus.