【问题标题】:Swift protocol error: 'weak' cannot be applied to non-class typeSwift 协议错误:“弱”不能应用于非类类型
【发布时间】:2016-02-01 23:54:44
【问题描述】:

Protocols 和 class-bound Protocols 有什么区别,我们应该在 Swift 中使用哪一种?

protocol A : class { ... }

protocol A { ... }

当协议未定义为 : class 时,尝试添加 weak 委托时出现错误:

protocol A { ... }

weak var delegate: A

给出错误:

'weak'不能应用于非类类型

'weak' 不能应用于非类绑定'A';考虑添加具有类绑定的协议一致性

【问题讨论】:

    标签: swift protocols


    【解决方案1】:

    斯威夫特 >= 4:

    protocol A : AnyObject { ... {
    

    斯威夫特

    protocol A : class { ... }
    

    定义了一个"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
    }
    

    这不会编译,因为对于结构和枚举的实例,a.name = "bar"a 的突变。如果你定义 协议为

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

    然后编译器知道a 是一个类类型的实例 a 是对对象存储的引用, a.name = "bar" 修改引用的对象,但不修改 a

    一般来说,如果需要,您会定义一个仅类协议 采用协议的类型是引用类型而不是值类型。

    【讨论】:

    • 在您的代码示例中,您说'a' is a 'let' constant。我有点困惑。是什么让 a 成为常​​量?
    • @Suragch:函数参数——就像func foo(a : A)中的a——默认是常量
    • "因此,如果您的协议定义了一个弱属性" - 协议没有定义weakstrong 属性(仅@ 987654338@和get set);不应该写成:“因此,如果符合协议的对象需要存储在弱属性中……”
    【解决方案2】:

    您可以使协议派生自任何类类型,例如 NSObject 或 AnyObject:

    protocol TopNewsTableDelegate : AnyObject {
        func topNewsTableDidLoadedStories()
    }
    

    【讨论】:

      【解决方案3】:

      或者你可以这样输入

      @objc protocol A { ... }
      

      那么你可以做一个弱委托引用

      【讨论】:

        【解决方案4】:
        protocol CustomProtocolName : NSObjectProtocol {
          // ...
        }
        

        【讨论】:

          【解决方案5】:

          如果您使用的是 Swift 4 或更高版本,请使用AnyObject

          protocol A : AnyObject { ... }
          

          像以前一样使用class 会给出警告并修复它:

          不推荐使用'class'关键字来定义类约束协议;改用“AnyObject”

          用“AnyObject”替换“类”

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-05-21
            • 2016-08-17
            • 1970-01-01
            • 2018-02-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多