Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retain Cycle in Swift delegate [duplicate]

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?

like image 668
Bocaxica Avatar asked Jul 15 '15 13:07

Bocaxica


People also ask

What causes retain cycle Swift?

Retain cycles: This is the state when two objects hold weak references to one another. Since the first object's reference count cannot be 0 until the second object is released, and the second object's reference count cannot be 0 until the first objet is released neither object can be released!

How do I fix retaining cycle in Swift?

In order to prevent this retain cycle, we need to declare at least one of the variable as weak or unowned. We can break the retain cycle with adding a weak keyword before either the driver property of the Car class or the car property of the Person class.

Which of the following can cause a retain cycle?

Structs and Classes A choice between a struct and a class can cause a retain cycle. Both structs and classes can have constants, variables, functions and protocols.

What's retain cycle how you can avoid?

Avoiding retain cycles rule #1: An object must never retain its parent. The first rule to avoid retain cycles is that an object must never retain its parent. This changes the previous diagram to the following: This is the easy case: an object should never retain its parent when it makes a pointer to the parent.


1 Answers

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: class {

}

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

like image 129
Aaron Brager Avatar answered Sep 24 '22 09:09

Aaron Brager