弱属性符合具有通用约束的协议

时间:2019-01-27 05:35:47

标签: swift generics protocols

我写了遇到问题的类似实现的简化版本。任何人都知道为什么会这样,最终知道如何解决?

注意:代码只是使代码尽可能简单的示例

protocol Alertable {
   associatedtype Alert

   func show(alertOfType alertType: Alert)
}
protocol ViewControllerDelegate: class, Alertable {
}

final class MyViewController: UIViewController {

   // MARK: - Types

   enum AlertType {
      case alert
      case warning
   }
}

extension MyViewController: ViewControllerDelegate {
   typealias Alert = AlertType   // ! here i specify the associated type !

   func show(alertOfType alertType: Alert) {
      // code..
   }
}

到目前为止,一切都很好。但是,这里出现错误:

final class ViewModel {

   // ERROR: Protocol 'ViewControllerDelegate' can only be used as a generic constraint because it has Self or associated type requirements.
   weak var viewController: ViewControllerDelegate?

   init(viewController: ViewControllerDelegate?) {
      self.viewController = viewController
   }

   private func someFunction() {

      // ERROR: Member 'show' cannot be used on value of protocol type 'NewsFeedViewControllerInput'; use a generic constraint instead.
      viewController?.show(alertOfType: .warning)

      // code..
   }
}

谢谢

1 个答案:

答案 0 :(得分:0)

您在这里有点误会。定义时:

protocol ViewControllerDelegate: class, Alertable {}

extension MyViewController: ViewControllerDelegate {
    typealias Alert = AlertType   // ! here i specify the associated type !

    func show(alertOfType alertType: Alert) {
        // code..
    }
}

类型别名是在MyViewController中定义的,而不是在ViewControllerDelegate中定义的。目前尚不清楚为什么在这个问题中需要ViewControllerDelegate,但也许有些东西在我们的实际应用中看不到。

ViewModel中,从ViewControllerDelegate更改为MyViewController

final class ViewModel {
    weak var viewController: MyViewController?
    // ...
}

还有另一件事,尽管与错误无关:您使用了许多final class。应该改为struct吗?