Why Can the Keyword "Weak" Only Be Applied to Class and Class-Bound Protocol Types

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

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.

Weak property in a Swift protocol may only be a class or class-bound protocol type

Protocols can't currently require properties to be implemented as weak stored properties.

Although the weak and unowned keywords are currently allowed on property requirements, they have no effect. The following is perfectly legal:

class C {}

protocol P {
weak var c: C? { get set }
}

struct S : P {
var c: C? // strong reference to a C instance, not weak.
}

This was filed as a bug, and SE-0186 will make the use of weak and unowned on property requirements in a protocol a warning in Swift 4.1 (in both Swift 3 and 4 modes), and an error in Swift 5.

But even if protocols could require properties to be implemented as weak or unowned stored properties, the compiler would need to know that ViperViewClass is a class type (i.e by saying
associatedtype ViperViewClass : AnyObject).

weak' may only be applied to class and class-bound protocol types, not '(ViewController) - () - ViewController'

At the point when your property initializer runs, self is not yet available. You'll need to use lazy loading — which is pretty easy. Just add lazy in front of the var.

lazy var myAction: ((Int, Bool) -> Void)? = { [weak self] int, bool in

}

Swift. unowned may only be applied to class and class-bound protocol types. weak works fine

As you already know, unowned cannot be optional but weak may be nil at some point.

From what I understand, unowned variable is different from implicitly unwrapping optionals. Implicit unwrapping is for variables, which may be nil, but we already know this variable is not nil at the exact point of access. However, unowned variable can never be nil at any point.

Thus, you can't use unowned constant of type ObserverProtocol!. You need to get rid of !.

But if you do get rid of !, Observer needs an initializer that initializes responder.

Swift protocol error: 'weak' cannot be applied to non-class type

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.



Related Topics



Leave a reply



Submit