【问题标题】:Protocol inheritance issue协议继承问题
【发布时间】:2016-10-14 09:35:54
【问题描述】:

我尝试建立各种协同工作的协议。不幸的是,我无法让它们按我想要的方式工作。看下面的代码,我想我的目标很明显:我想要一个符合协议 X 的类。如果它符合协议 Y,但协议 Y 继承自协议 X,它也应该被接受为符合协议的类.相反,我收到以下编译错误

Unable to infer associated type 'VC' for protocol 'ViewModelType'

Inferred type 'ExampleViewControllerType' (by matching requirement 'viewController') is invalid: does not conform to 'ViewType'

当前设置:

protocol ViewModelType: class {
    associatedtype VC: ViewType
    weak var viewController: VC! { get set }
}

class ExampleViewModel: ViewModelType {
    weak var viewController: ExampleViewControllerType!
}

protocol ViewType: class { }    
protocol ExampleViewControllerType: ViewType { }

class ExampleViewController: UIViewController, ExampleViewControllerType { 

}

【问题讨论】:

标签: ios swift protocols associated-types protocol-inheritance


【解决方案1】:

我可以看到您对“传递”协议的理解,但是您的错误是由您在错误中看到的associatedtype VC 声明引起的。

Unable to infer associated type 'VC' for protocol 'ViewModelType'

我认为编译器在这里遇到困难可能是因为它不当使用了associatedtype 声明。

associatedtype 可以被认为是未知类型的占位符。

通过将VC 定义为associatedtype,您可以让任何继承ViewModelType 的类决定VC 应该是什么类型。

ExampleViewModel 类中,您可以通过在符合类中使用typealias 设置类型来做到这一点。

然后您的 viewController 可以是 ExampleViewControllerType 而不会导致“推断”错误

protocol ViewModelType: class {
    associatedtype VC
    var viewController: VC! { get set }
}

class ExampleViewModel: ViewModelType {
    typealias VC = ExampleViewControllerType
    weak var viewController: ExampleViewControllerType!
}

protocol ViewType: class { }
protocol ExampleViewControllerType: ViewType { }

class ExampleViewController: UIViewController, ExampleViewControllerType {

}

【讨论】:

  • 我还删除了 ViewModelType 协议中 viewController 的弱 var 声明,因为在类和类绑定协议类型中似乎不允许使用弱 var。
  • 在您的示例中 exampleViewModel.viewController 不必遵守协议 ViewType 但这是我喜欢的。
  • 啊哈!我知道我没有正确回答你的问题!我对错误本身有远见,但现在我明白你的意思了。我认为 Sahil 的答案是正确的,我的答案代码只是说明了他的观点。
【解决方案2】:

不!它不能是符合类(如果它符合协议 Y,但协议 Y 继承自协议 X,它也应该被接受为符合类)。一个协议可以继承一个或多个其他协议,并且可以在它继承的要求之上添加进一步的要求。协议继承的语法类似于类继承的语法。您不能扩展协议以符合另一个协议。只有一个类满足协议强制执行的所有要求。您可以扩展协议以提供默认实现。

extension Y {
  // default implementations 
}

了解更多Protocol Inheritance

【讨论】:

  • 这在我的场景中实际上并不太有用,用于扩展我的协议 X - 我只想在使用更具体的协议(它们本身符合该 ViewType 类)的同时强制执行一个通用的 ViewType 类每个场景。无论如何,我想我(再次)意识到这是不可能的,除非我像 ExampleViewModel<VC: ExampleViewControllerType> 那样将关联类型放在类的定义中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-24
  • 1970-01-01
相关资源
最近更新 更多