Skip to main content

4 questions tagged with "Memory Management"

Memory Management tag description

View All Tags

How would you avoid retain cycles in a closure?

· 2 min read
Ace the iOS Interview
Aryaman Sharda
Sources & Resources

Main Source: đź”— Ace the iOS Interview

Additional Sources:

Further Reading:

TL/DR

This will build off our understanding of ARC from the previous questions.

Often times, closures will introduce retain cycles. Since a closure is a reference type it maintains a strong reference to all of the objects referenced in the body of the closure thereby increasing their retain count.

To manage this, we can use a capture list. This allows us to explicitly specify which objects we want to maintain a reference to, but more importantly whether we want those references to be weak, strong, or unowned.

We can pick weak or unowned(where applicable) to ensure that we can still reference all of the objects the closure needs, but we don’t inadvertently increase their retain count and introduce a retain cycle.

The following example has a retain cycle as the body of the closure creates a strong reference to isUserActive and isUserOnlineView.

class RetainCycleDemo {
@IBOutlet var isUserOnlineView: UIView!

var isUserActive = false

func setUserActivityStatusView() {
userService.checkUserOnlineStatus { isOnline in
self.isUserActive = isOnline

if isOnline {
self.isUserOnlineView.backgroundColor = .green
} else {
self.isUserOnlineView.backgroundColor = .red
}
}
}
}

Fortunately, we can fix this by simply using a weak reference to self instead. And, voila - no more retain cycles!

class RetainCycleDemo {
@IBOutlet var isUserOnlineView: UIView!
var isUserActive = false

func setUserActivityStatusView() {
userService.checkUserOnlineStatus { [weak self] isOnline in
self?.isUserActive = isOnline
if isOnline {
self?.isUserOnlineView.backgroundColor = .green
} else {
self?.isUserOnlineView.backgroundColor = .red
}
}
}
}

What is a memory leak?

· One min read
Ace the iOS Interview
Aryaman Sharda
Sources & Resources

Main Source: đź”— Ace the iOS Interview

Additional Sources:

Further Reading:

TL/DR

Memory leaks occur when a program incorrectly manages memory allocations such that memory that is no longer needed is not released. Additionally, it is also possible for a memory leak to occur when an object is in memory, but cannot be accessed by the running application.

In iOS, most memory leaks are a result of retain cycles.

This occurs when two entities keep astrongreferenceto one another. Since these entities' respective retain counts would be non-zero, ARC (automatic reference counting) would be unable to release either one.

The advantage of keywords likeweakorunownedisthat they allow us to create references to other objects without affecting their retain count. As a result, most memory leaks can be mitigated by making the offending referenceweakorunowned.

If we need to debug a memory leak, we can use Xcode’s Memory Graph Tool or the Leaks profiling template within Instruments.

What is automatic reference counting?

· 2 min read
Ace the iOS Interview
Aryaman Sharda
Sources & Resources

Main Source: đź”— Ace the iOS Interview

Additional Sources:

Further Reading:

TL/DR

In simple terms, ARC is a compile time feature that helps us manage memory on iOS. ARC simply counts how many strong references there areto an object and when the count is zero, that object can be freed from memory.

Remember only a strong reference increases the retaincount; a weak or unowned reference has no effect on the object’s retain count. In iOS, a strong reference is the default.

Imagine that there is some UIViewController that implements a delegate. Since we’re using a strong reference, we know the UIViewController is intentionally increasing the delegate’s retain count to prevent it from being cleared from memory. In turn, the delegate has a weak reference back to the UIViewController so there’s no change to the UIViewController’s retain count.

Instead, if we had a strong reference from the delegate back to the UIViewController, that would increment the retain count of the UIViewController.

Now, both items would have a retain count of one and neither object could ever be freed; the UIViewController depends on the delegate and the delegate depends on the UIViewController.

This is what we call a retain cycle.

We can prevent this retain cycle by making the delegate have a weak reference to the implementing object. Oftentimes, whenever a child object has a reference to its parent object, we’ll make it a weak reference in order to avoid this exact issue.

That’s why you’ll commonly see delegates declared with the weak keyword like this:

class LocationManager {
weak var delegate: LocationManagerDelegate?
}

Note that the delegate is an Optional as anything with a weak reference can be nil during its execution.

What is the difference between strong, weak, and unowned?

· One min read
Ace the iOS Interview
Aryaman Sharda
Sources & Resources

Main Source: đź”— Ace the iOS Interview

Additional Sources:

Further Reading:

TL/DR

Please see the previous answer’s explanation of Automatic Reference Counting.

All of these keywords are different ways of describing how one object maintains a reference to another object.

strongis the default keyword in iOS and will incrementthe reference count of whatever object it’s referring to.

weak does not increment the reference count and the object it references can be nil. This is commonly used when working with delegates.

unowned does not increment the reference count either,but promises that the value it references will not be nil during its lifetime.