8

After reading some posts here regarding this issue, I discovered that my protocol should inherit from 'class' in order for 'weak' to work on my delegate variable.

'weak' may only be applied to class or class-bound protocol types.

If my protocol does not inherit from 'class', does swift 'infer' that it should be weak?

Is this the de facto way for casting a variable of type 'protocol' to weak ?

What happens in terms of memory management

protocol FacebookLoginViewControllerDelegate: class {
    func facebookLoginViewControllerDidLogin(controller: FacebookLoginViewController)
}

class FacebookLoginViewController: UIViewController {

    weak var delegate: FacebookLoginViewControllerDelegate?

}
  • Is this helps you http://stackoverflow.com/a/24104371/1371853 – swiftBoy May 10 '16 at 07:51
  • 1
    I'm unsure what you're asking here... Making a protocol class bound (`: class`) simply tells the compiler that it can only ever represent a reference type – and therefore you can use `weak` on it. You cannot make a value type `weak`, as ARC (automatic *reference* counting) works with references, not with values. – Hamish May 10 '16 at 08:03
  • seems like a reasonable answer. fancy posting that as an answer ? –  May 11 '16 at 07:27
  • @robdashnash Sure thing :) I only didn't post it as an answer as I wasn't initially 100% sure what you were asking! So just to clarify, your question is basically "Do I have to make my protocol class bound in order to use weak on it?" – Hamish May 11 '16 at 11:34

1 Answers1

12

Making a protocol class bound with : class simply tells the compiler that it can only ever represent a reference type – and you can therefore use the weak attribute on it.

If you don't mark a protocol as being class bound, then Swift will assume that it could be representing either a reference or value type. Because ARC (automatic reference counting) only works with references, and not values, then the compiler will prevent you from being able to put the weak attribute on it.

The reason that ARC doesn't work with value types is that because they get copied when you pass them around, instead of being passed around by reference. Therefore their memory can easily managed as their lifetime is super predictable, unlike reference types.

For reference types, if you're using a delegate pattern, then the delegate should always be weak in order to avoid retain cycles – and therefore the protocol should always be class bound. Using a value type for a delegate makes next to no sense, as it'll always refer to a copy of what you assigned to it.

Hamish
  • 78,605
  • 19
  • 187
  • 280
  • Did I get this right: If I want to be able to let structs and classes conform to my protocol, there is no way to avoid retain cycles? – shallowThought Nov 29 '17 at 08:55
  • @shallowThought I mean, you *could* build a wrapper type for this (https://gist.github.com/hamishknight/71b851e495c46f036110e509d2cad63b), but this probably suggests something wrong with your protocol design; if you want weak reference semantics, the conforming types really should all be reference types (so the protocol should be class bound). Do you have a use case for this, or are you just curious? – Hamish Dec 17 '17 at 20:30
  • I have a `class` `A` that has a `delegate` `property`. All current delegates are classes. Now I was writing a delegate for a new situation and, as I try to prefer `struct`s over `class`es wherever I can, I implemented it a `struct`, which is not possible for the other delegates (they have an identity). Due to the topics issue, I had to make it a class then. – shallowThought Dec 21 '17 at 13:22
  • 1
    @shallowThought Yes, that's the right way to go; it doesn't really make much sense for something with value semantics to be a delegate. – Hamish Dec 21 '17 at 18:57
  • Now that I think of it, you are right. It does not make any sense :-) – shallowThought Jan 09 '18 at 21:43