Mallow's Blog

Ways to detect the Memory Leaks in Swift

Managing memory and avoiding leaks is a crucial part of any programming language. Memory leaks happen certain memory is allocated to set of objects but deallocation is never initiated. Hence the system can never reclaim the allocated memory which eventually means it will run out of available memory for an app.

Swift uses Automatic Reference Counting (ARC) for memory management. However, there are situations in which retain cycles occur(holding a strong reference to an object which indeed is a reference to other).

Retention cycles in Delegates

Delegates enable loosely coupled relationship between objects but delegates are been referenced strongly.Consider the following case,

Class ViewController {</span>

<span style="font-weight: 400;">     var delegate: delegateName?</span>

<span style="font-weight: 400;">}

The above code will likely cause retain cycle, as the owner of a ViewController instance will probably also be its delegate – causing both of the objects to strongly reference each other. To solve the retain cycle we need to Introduce weak var.

Class ViewController {</span>

<span style="font-weight: 400;">     var weak delegate: delegateName?</span>

<span style="font-weight: 400;">}

We only need to use weak if the delegate is a class. Swift structs and enums are value types(not reference types), so they don’t make strong reference cycles.

Note:- There is no weak let. When we use weak, the property should be optional and mutable in order to set it as nil or assign a value to the delegate property.

Retention Cycle in Closures

Similar to the delegates, closure types also account to retain cycles.

manager.add { self in</span>

<span style="font-weight: 400;">         print(“\(self.value) in Closure”)</span>

<span style="font-weight: 400;">}

In above case, the closure block contains a reference to the property which causes leaks. Any code in a closure that refers to self. is a potential memory leak.This can be solved by adding [unowned self] or [weak self].

Identifying memory leaks

The Xcode memory graph debugger helps to find and fix to retain cycles and leaked memory. When activated, it pauses app execution, and displays objects currently on the heap, along with their relationships and what references are keeping them alive.

To activate graph debugger, Opt in to stack logging integration via the Xcode scheme editor. Note that we only enable logging of ‘Live Allocations’. This has a lower overhead than ‘All Allocations’ when debugging, and is all we need to identify retain cycles and leaks.

Memory Leak 1

Perform the actions that are suspected to cause retain cycles. Finally, enter the memory graph debugging mode by selecting its debug bar button. The memory graph debugger pauses app execution and displays the following:

memory leak 2

On the left, the debug navigator displays the app’s heap contents. Selecting an instance from the debug navigator shows the instances references in the centre pane. Selecting an instance in the centre reference pane displays general object memory information and the allocation backtrace in the right-hand inspector pane. Leaks are displayed in the debug navigator.

In this blog, we have seen the common mistakes causing retain cycles and ways to detect leaks in an app. In upcoming blogs, we will learn more about debugging tools and approaches to avoid the retain cycles.


Poorvitha Y,
iOS Team,
Mallow Technologies.

 

Leave a Comment

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