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 struct
s 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 thata
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
Writing Data to an Nsoutputstream in Swift 3
How to Change Font Size and Font Name of Uisegmentedcontrol Programmatically on Swift
Is Swift a Dynamic or Static Language
Swift - Drawing Text with Drawinrect:Withattributes:
Swift Function with Args... Pass to Another Function with Args
Swift Protocol and Return Types on Global Functions
Is There a Difference Between "Is" and Iskindofclass()
Trouble Left-Aligning Uibutton Title (Ios/Swift)
Present Uiviewcontroller as a Modal with Transparent Background
Rxswift Map and Flatmap Difference
How to Link a .Sks File to a .Swift File in Spritekit
Firebase Storage Downloadurl()' Is Deprecated: Use 'Storagereference.Downloadurlwithcompletion()
Swiftui - Two Buttons in a List
How to Copy a Struct and Modify One of Its Properties at the Same Time
Protocol Extension on an Objc Protocol