Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 具有关联类型和可选方法的协议_Swift - Fatal编程技术网

Swift 具有关联类型和可选方法的协议

Swift 具有关联类型和可选方法的协议,swift,Swift,我想制作一个数据源协议,包括: 关联类型 可选方法 e、 g.(目前,使用Swift 4.1编译下面截取的代码失败) 此代码失败,出现无法读取的错误: 0x0x7fdede80c9a0 Module name=tabbedApp 0x0x7fdede1a8020 FileUnit file="/Users/gvr/Developer/freelance/tabbedApp (1.2)/tabbedApp/Utilities/DataSource.swift" 0x0x7fdede

我想制作一个数据源协议,包括:

  • 关联类型
  • 可选方法
e、 g.(目前,使用Swift 4.1编译下面截取的代码失败)

此代码失败,出现无法读取的错误:

0x0x7fdede80c9a0 Module name=tabbedApp
  0x0x7fdede1a8020 FileUnit file="/Users/gvr/Developer/freelance/tabbedApp (1.2)/tabbedApp/Utilities/DataSource.swift"
    0x0x7fdede1a83e0 ProtocolDecl name=DataSourceNotWrkng
      0x0x7fdede1a8a30 AbstractFunctionDecl name=_ : <<error type>>
(error_type)
0x0x7fdede80c9a0模块名称=tabbedApp
0x0x7fdede1a8020文件单元文件=“/Users/gvr/Developer/freeloper/tabbedApp(1.2)/tabbedApp/Utilities/DataSource.swift”
0x0x7fdede1a83e0 ProtocolDecl name=DataSourceNotWrkng
0x0x7fdede1a8a30抽象函数DECL名称=\uU7:
(错误类型)

您不能同时使用关联类型和Objective-C协议。具有关联类型的协议在Objective-C中不可见,并且Objective-C协议不能具有关联类型

原因是关联类型是一种静态分派功能,而Objective-C协议依赖于运行时功能,因此它们不能在同一协议中共存

编译器不应该允许您这样做,但是似乎有一个bug使它在给出正确的错误消息之前崩溃

请注意,像可选功能这样的功能可以通过使用默认实现而不是
@objc
协议来实现。这将允许您继续使用协议及其关联类型:

protocol MyDataSource {
    associatedtype Item

    var array: [Item] { get set }

    // moved the optionality to the method result level
    func titleForHeader(in section: Int) -> String?
}

extension MyDataSource {
    // conforming types no longer need to implement this method,
    // if they don't want to, they will get the default implementation
    func titleForHeader(in section: Int) -> String? {
        return nil
    }
}

…或者我可以使用titleForHeader的可选闭包作为可获取属性,比如:var titleForHeader:((在节中:Int)->String?)?{get}。init是采用这种协议的init类。尽管我不喜欢这两种解决方案。谢谢你的解释@IevgenGavrysh是的,您可以使用可选属性,但是这种方法与函数具有相同的缺点,同时具有“更难看”的语法。
protocol MyDataSource {
    associatedtype Item

    var array: [Item] { get set }

    // moved the optionality to the method result level
    func titleForHeader(in section: Int) -> String?
}

extension MyDataSource {
    // conforming types no longer need to implement this method,
    // if they don't want to, they will get the default implementation
    func titleForHeader(in section: Int) -> String? {
        return nil
    }
}