【问题标题】:"self as?" within protocol extension“自己呢?”协议扩展内
【发布时间】:2018-04-17 01:04:46
【问题描述】:

我试图在协议扩展中投射“自我”。它在真实设备上运行时因 EXC_BAD_ACCESS 错误而崩溃,但在模拟器上运行良好。我应该怎么做才能使这项工作?谢谢

我的整个代码:

protocol SomeProtocol: class {

}

protocol DataSetEditable {
    func add(_ data: Data)
}

extension DataSetEditable where Self: SomeClass {
    func add(_ data: Data) {
        print(data)
        if let someProtocol = self as? SomeProtocol {
            print(someProtocol)
            //do some extra works
        }
    }
}

class SomeClass: UIView {

}

class MyClass: SomeClass, DataSetEditable, SomeProtocol {
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let myClass = MyClass()
        myClass.add(Data())
    }
}

【问题讨论】:

    标签: swift casting protocol-extension


    【解决方案1】:

    首先,这可能是一个 Swift 错误,因为如果编译器无法处理这个错误,它应该会提供一个错误。您应该在bugs.swift.com 打开它。这感觉和SR-544有关。

    也就是说,通常将 ObjC 类型与 Swift-only 协议保持一致是非常棘手的。有时有效,有时无效。这是一个相当复杂的一致性,显然它并不总是有效。解决方案是通过添加@objc将协议暴露给ObjC:

    @objc protocol SomeProtocol: class {}
    

    【讨论】:

    • 它对我有用。我会报告这个错误,感谢您的帮助。
    【解决方案2】:

    您可以尝试像下面这样扩展 DataSetEditable。

    extension DataSetEditable where Self: SomeClass & SomeProtocol {
      func add(_ data: Data) {
       ...
      }
    }
    

    现在上面的扩展方法func add(_ data: Data)只能被SomeClass的子类访问,并且跟在SomeProtocol之后。

    【讨论】:

    • 我不能这样做,因为我有另一个类,它是 SomeClass 的子类并且不符合 SomeProtocol 协议。这样AnotherClass就不能使用add(_data:Data)函数,必须自己实现add(_data:Data)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多