Strong vs. Weak Properties, Why are they important?

Matthew Goo
3 min readAug 23, 2015

--

At first brush this topic eluded me as to why this is so important in iOS development. I first thought, “oh strong and weak typed languages”. But diving further into the topic I found is related to memory management. But why do we need to care about memory management? Why does this matter when the language handles this for us? One would think if something is automated the intent is to make our lives easier, and that we better not touch it otherwise we’d throw off the system and result in crashing applications (if it ain’t broke don’t fix it). This is so far from the truth, especially with mobile development. We may have come a far way from the times of punch cards and floppys, but consumer expectations concerning performance and ease of use have increased at a rate higher than Moore’s Law. So let me share with you what I’ve learned about strong and weak properties in Swift.

Swift uses ARC* to track and manage memory. Every time you create an instance of a class, ARC will allocate a new chunk of memory to store this instance. When the instance is no longer being used, ARC will deallocate that instance. ARC is pretty smart and will not deallocate any instance that is still being referred/pointed to. These types of references are called strong references, since they have a strong hold on the instance of the object. There are some occasions that this system breaks down that a Swift iOS developer should be aware of, one of the most common of them are strong reference cycles between class instances.

*ARC for those that haven’t heard of this term is automatic reference counting and serves the same purpose as the garbage collector.

Strong reference cycles occur when there are two classes, class A and class B that have properties that reference each other. There are 4 strong references here at play, 2 variables that refer to the class instances and a property within each class that refer to the other. When we dereference the 2 class variables pointing to the instances, we would expect the two instances to be deallocated since we have no reference them. But because of the 2 properties that refer to the other, they keep each other alive.

In order to resolve this issue, it is important to set at least one of the class properties as a weak or unowned property. Whether you set it to weak or unowned is determined by whether or not your variable will be of optional type. If you know that your property will always reference something (non-optional type), then that property can be of type unowned. On the other hand if it can/will be nil (optional type), then it should be set to type weak. This breaks the strong reference cycle since one of the class instances won’t have a strong reference to it, which indicates ARC to deallocate the instance.

There is another occasion that will create a strong reference cycle, which occurs between a closure and a class. Please refer to code below for clarification:

class MyClass {
let isAwesome: Bool?
lazy var isSwiftAwesome: () -> String = {
if let isAwesome = self.isAwesome {
return “Yes, most definitely”
} else {
return “Maybe”
}
}
init(isAwesome: Bool) {
self.isAwesome = isAwesome
}
}

After we initialize an instance of this class, myClass will a strong reference to the closure, isSwiftAwesome within the body declaration. isSwiftAwesome will reference myClass with the keyword self. The class’s strong reference to the closure isSwiftAwesome and the strong reference to myClass from within the closure keeps the two elements alive. The way in which you resolve this issue is through a capture list. By defining the closure with a capture list, you can list the arguments taken by the closure and indicate that they are weak or unowned types so ARC knows to deallocate the appropriate instances.

Hopefully my post doesn’t confuse you further if you were looking for an answer, that wasn’t my intent. What I do hope is that this illustrates that ARC in Swift simplifies our lives, but does have some holes that we must be aware of as developers (if it ain’t broke, fix it). We all want performant applications, but must take the time to learn the details in order to acheive our goals.

--

--