Search code examples
iosswiftdelegatesretain-cycle

Retain Cycle in Swift delegate


I have a UIViewController and in it a UIToolbar. They get instantiated from a storyboard.

I made a custom class for my UIToolbar. Based on some logic I do or do not show buttons on it.

The UIViewController needs to take action when some of the buttons are tapped. For this I created a delegate protocol in the UIToolbar.

Currently, when I dismiss the view, it is kept in memory. Further investigation revealed my delegate created a retain cycle.

In Objective-C, we would simply define delegates as weak. However, I am using Swift, and it does not allow me to define delegate variable as weak:

weak var navigationDelegate: MainToolBarDelegate?
// 'weak' cannot be applied to non-class type 'MainToolBarDelegate'

When I dismiss the view controller, I set self.toolBar.navigationDelegate = nil and the memory gets cleared. But it feels wrong!

Why do I get the retain cycle and why can I not simply define the delegate as weak?


Solution

  • weak references only apply to classes, not structs or enums, which are value types. But protocols by default can apply to any of those types.

    Define your MainToolBarDelegate as a class-only protocol:

    protocol MainToolBarDelegate: AnyObject {
    
    }
    

    Then you'll be able to declare your delegate as weak.