Memory Management In iOS Applications

In any language that passes values by reference memory management will need to be front of mind. In iOS you can use the memory graph and on Android you have the Memory Profiler to help you trace unreleased objects and mitigate leaks.


Scenario

Say you want to an object to be notified when changes occur within another object. You could pass the first object to the second and the second could call the first’s pubic methods to communicate the change. What you create is a cyclical dependency where object two cannot be released until object one is released and vice versa.

class One: Listener {
    val objectOfClassTwo = Two(listener: self)
    
    // Inherited from Listener
    public func onEmit(){ ... } 
}

class Two {
    let listener: Listener

    init(listener: Listener) {
        self.listener = listener
    }

    func doStuff() {
        self.listener.onEmit()
    }
}

Under The Hood

The Clang compiler developed by Apple and employed in their operating systems uses Automatic Reference Counting (ARC) to manage memory – how it does this is written on the tin. When the reference count for any object drops to zero the object is released and the memory it was occupying is freed. One and Two now hold a reference to each other and neither can be released.


Example

We can take the scenario above and put it into a UIViewController to see how this might affect our applications in the real world. iOS will allow us to carry on pushing and popping the stack and when we open up the memory graph we will find all instances of One and Two still allocated in memory.

The purple exclamation marks indicate an object that has leaked

Although this application is tiny and contains no views, it’s easy to see how this could cause problems such as Out Of Memory (OOM) errors.

Leave a Reply

Your email address will not be published. Required fields are marked *