Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weak' must not be applied to non-class-bound consider adding a protocol conformance that has a class bound [duplicate]

What's the difference between Protocols and class-bound Protocols, and which one we should use in Swift?

protocol A : class { ... }  protocol A { ... } 

We get an error when attempting to add a weak delegate when the Protocol is not defined as : class:

protocol A { ... }  weak var delegate: A 

Gives the error:

'weak' cannot be applied to non-class type

or

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

like image 780
boog Avatar asked Nov 02 '15 06:11

boog


People also ask

How do you make a weak protocol Swift?

Protocols can be used for both reference types (classes) and value types (structs, enums). So in the likely case that you need to make a delegate weak, you have to make it an object-only protocol. The way to do that is to add AnyObject to the protocol's inheritance list.

Is it possible to prevent the adoption of a protocol by a struct?

The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements. But there would be a time when you want to restrict protocols to be adopted by a specific class. In Swift 5, you can do just that.

What is a swift protocol?

In Swift, a protocol defines a blueprint of methods or properties that can then be adopted by classes (or any other types). We use the protocol keyword to define a protocol. For example, protocol Greet { // blueprint of a property var name: String { get } // blueprint of a method func message() }


1 Answers

Swift >= 4:

protocol A : AnyObject { ... { 

Swift < 4:

protocol A : class { ... } 

defines a "class-only protocol": Only class types (and not structures or enumerations) can adopt this protocol.

Weak references are only defined for reference types. Classes are reference types, structures and enumerations are value types. (Closures are reference types as well, but closures cannot adopt a protocol, so they are irrelevant in this context.)

Therefore, if the object conforming to the protocol needs to be stored in a weak property then the protocol must be a class-only protocol.

Here is another example which requires a class-only protocol:

protocol A {      var name : String { get set } }  func foo(a : A) {     a.name = "bar" // error: cannot assign to property: 'a' is a 'let' constant } 

This does not compile because for instances of structures and enumerations, a.name = "bar" is a mutation of a. If you define the protocol as

protocol A : class {      var name : String { get set } } 

then the compiler knows that a is an instance of a class type to that a is a reference to the object storage, and a.name = "bar" modifies the referenced object, but not a.

So generally, you would define a class-only protocol if you need the types adopting the protocol to be reference types and not value types.

like image 65
Martin R Avatar answered Sep 18 '22 11:09

Martin R