11

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?

Aaron Brager
  • 65,323
  • 19
  • 161
  • 287
Bocaxica
  • 3,911
  • 3
  • 37
  • 54
  • 2
    Is your NavigationDelegate a protocol (as opposed to a [class-only protocol](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID281)?) If it's just a standard protocol, there's no guarantee that your actual object will be a class instance rather than a structure, hence "Cannot be applied to non-class type"; if it could be a structure or an enum, then it can't be `weak`, as it might not be a reference type. – Matt Gibson Jul 15 '15 at 14:02

1 Answers1

18

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.

Lukáš Kubánek
  • 946
  • 1
  • 15
  • 27
Aaron Brager
  • 65,323
  • 19
  • 161
  • 287
  • do you know if there is any difference between using : class or : NSObjectProtocol – user2363025 Feb 06 '18 at 14:17
  • 2
    @user2363025 `class` means any class, and `NSObjectProtocol` means anything that conforms to this protocol. I would use `class` unless you have a specific reason to use `NSObjectProtocol`. – Aaron Brager Feb 07 '18 at 02:51