简体   繁体   English

swift 协议“弱”不能应用于非类类型

[英]swift protocol 'weak' cannot be applied to non-class type

I'm a bit confused.我有点困惑。 What's the difference between protocol A : class { ... } and protocol A{ ... } , and which one we should use in swift? protocol A : class { ... }protocol A{ ... }之间有什么区别,我们应该在 swift 中使用哪一个?

PS: we got an error when we wrote like this PS:我们这样写的时候报错

protocol A{ ... }

weak var delegate: A

error : 'weak' cannot be applied to non-class type错误:“弱”不能应用于非类类型

Swift >= 4:斯威夫特> = 4:

protocol A : AnyObject { ... {

Swift < 4:斯威夫特 < 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 .这不会编译因为结构和枚举的实例a.name = "bar"是一个突变的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 .然后编译器知道a是类类型的实例, a是对对象存储的引用,并且a.name = "bar"修改引用的对象,而不是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.所以一般来说,如果你需要采用该协议的类型是引用类型而不是值类型,你会定义一个仅限类的协议。

如果您使用的是Swift 4 及更高版本

protocol A : AnyObject { ... }

You can make the protocol derive from any class type like NSObject or AnyObject:您可以使协议从任何类类型派生,如 NSObject 或 AnyObject:

protocol TopNewsTableDelegate : AnyObject {
    func topNewsTableDidLoadedStories()
}

Or you can type like this或者你可以这样输入

@objc protocol A { ... }

then you can make a weak delegate reference然后你可以做一个弱委托引用

protocol CustomProtocolName : NSObjectProtocol {
  // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM