简体   繁体   中英

Protocols with associated type and optional methods

I would like to make a data source protocol with:

  • Associated type
  • Optional method

eg(currently, with Swift 4.1 compilation for code snipped below fails)

@objc protocol DataSourceNotWrkng {
    associatedtype Item

    var array: [Item] { get set }

    @objc optional func titleForHeader(in section: Int) -> String
}

class ComponentsDataSourceNotWrkng: DataSourceNotWrkng {
    typealias Item = Int

    var array: [Int]

    init(with array: [Int]) {
        self.array = array
    }
}

This code fails with unreadable error:

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)

You can't use both associated types and Objective-C protocols. Protocol with associated types are not visible into Objective-C, and Objective-C protocols can't have associated types.

The reason is associated types is a static dispatch feature, while Objective-C protocol rely on runtime features, so they can't live together in the same protocol.

The compiler should not allow you to do this, however seems there's a bug that makes it crash it before it can give you a proper error message.

Note that a feature like an optional function can be achieved by other means than an @objc protocol, by using default implementations. This will allow you to keep using the protocol and it's associated type:

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
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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