Why can the keyword "weak" only be applied to class and class-bound protocol types

SwiftVariablesWeak References

Swift Problem Overview


When I'm declaring variables as weak in Swift, I sometimes get the error message from Xcode:

> 'weak' may only be applied to class and class-bound protocol types

or

> 'weak' must not be applied to non-class-bound 'SomeProtocol'; consider adding a protocol conformance that has a class bound

I'm wondering why the keyword weak can only applied to class and class-bound protocol types? What is the reason behind this requirement?

Swift Solutions


Solution 1 - Swift

One common reason for this error is that you have declared you own protocol, but forgot to inherit from AnyObject:

protocol PenguinDelegate: AnyObject {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate: PenguinDelegate?
}

The code above will give you the error if you forget to inherit from AnyObject. The reason being that weak only makes sense for reference types (classes). So you make the compiler less nervous by clearly stating that the PenguinDelegate is intended for classes, and not value types.

Solution 2 - Swift

weak is a qualifier for reference types (as opposed to value types, such as structs and built-in value types).

Reference types let you have multiple references to the same object. The object gets deallocated when the last strong reference stops referencing it (weak references do not count).

Value types, on the other hand, are assigned by copy. Reference counting does not apply, so weak modifier does not make sense with them.

Solution 3 - Swift

protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate: PenguinDelegate?
}

If you type class after your protocol it works as well and seems more appropriate that for NSObjectProtocol.

Solution 4 - Swift

Well just in case anyone else thinks that you have everything correct in your code like me, check that you did not mistakenly replaced the : by an =.

Here is what I had. It was also giving me the same error as above:

protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate = PenguinDelegate?
}

But the correct way is:

protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate: PenguinDelegate?
}

Do you see the difference? It took me a while to see that I had an equal sign instead of a colon. Also note that I did get other errors for the same line for I had decided my first error seem like the most likely to be the real problem :

> -weak may only be applied to class and class-bound protocol types

:-<

Solution 5 - Swift

I find out in one case where you even have class type but still you get this error message.

For example,

class MyVC: UIViewController {
   var myText: UITextView = {
      [weak self]
      let text = UITextView()
      // some codes using self
      return text
   }()
}

Here an UITextView object is returned from an anonymous block as initialization of var myText. I got the same type of error message. To resolve the issue, the var has to be marked as lazy:

class MyVC: UIViewController {
   lasy var myText: UITextView = {
      [weak self]
      let text = UITextView()
      // some codes using self
      return text
   }()
}

Solution 6 - Swift

Just FYI and who is not updated. After swift proposal SE-0156 https://github.com/apple/swift-evolution/blob/master/proposals/0156-subclass-existentials.md was implemented, there is in the Swift docs "Class-Only Protocols section" https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID281 now described to use AnyObject instead of class. So, it is possible for : class to be deprecated in future.

Solution 7 - Swift

weak is for ARC(Automatic Reference Counting). It means not adding reference count. So it only works for Class. And in Swift, you will get optional value for security.

Solution 8 - Swift

I tried to capture String and Array-typed properties for a closure. I got these errors:

> 'weak' may only be applied to class and class-bound protocol types, not '[String]' > > 'weak' may only be applied to class and class-bound protocol types, not 'String'

I played a while in the playground, and it turned out, capturing self is enough for these types.

Solution 9 - Swift

enter image description hereI was using objective C class in swift for a scrolView. I created IBOutlet of that scroll view. And while compiling code this error started showing.

So to fix this kind of issue, import that class in your bridging header

> # import "YourClass.h"

I was using Xcode 9.2 with swift 3.2

Solution 10 - Swift

weak only works for reference type, so Xcode would report an error if you are calling from struct (instead of class).

Solution 11 - Swift

  1. weak is not for value type.
  2. weak comes to the picture only for the class.

"weak" can apply anything which is inherited from class or class-bound protocol types

  1. Class Protocol: protocol ViewControllerDelegate : class { func getInformationk(value: String?) }

  2. NSObjectProtocol:

    protocol ViewControllerDelegate : NSObjectProtocol { func getInformation(value: String?) }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThorView Question on Stackoverflow
Solution 1 - SwiftJakView Answer on Stackoverflow
Solution 2 - SwiftSergey KalinichenkoView Answer on Stackoverflow
Solution 3 - SwiftAaronium112View Answer on Stackoverflow
Solution 4 - SwiftPatrick MironView Answer on Stackoverflow
Solution 5 - SwiftDavid.Chu.caView Answer on Stackoverflow
Solution 6 - SwiftDrenView Answer on Stackoverflow
Solution 7 - SwiftLumialxkView Answer on Stackoverflow
Solution 8 - SwiftDisplay NameView Answer on Stackoverflow
Solution 9 - SwiftPramod MoreView Answer on Stackoverflow
Solution 10 - Swiftsuperarts.orgView Answer on Stackoverflow
Solution 11 - SwiftDivesh singhView Answer on Stackoverflow