繁体   English   中英

快速扩展框架中对象的协议一致性会导致无限循环

[英]Swift extension for protocol conformance on object in framework causes infinite loop

问题:模型对象在框架中定义,协议在应用程序目标中定义。 应用程序目标了解框架,但反之则不然,因此协议一致性不能出现在模型对象的声明中。

但是,模型对象已经具有实现协议所需的大多数字段(主要是var {get}声明),并且-显然这是摩擦-这些字段具有相同的名称。 实际模型中大约有20个属性。

毫不奇怪,以下模式会产生无限循环:

//Framework Target:  

public struct Book {
    public let numberOfPages : Int
}

//App target:

public protocol BookViewDataSource {
    var numberOfPages : Int { get }
}

extension Book : BookViewDataSource {
    public var numberOfPages : Int { return self.numberOfPages } 
}

但是有什么选择呢? 拒绝/失败的建议:

  1. 视图直接采用模型。 一种通用方法,总是很糟糕,因为它将视图和模型紧密结合在一起。 使用基于协议的接口可以在设计时和运行时轻松地与模拟对象交换。
  2. 不同的名字。 给协议属性和结构属性使用不同的名称是可行的,但是命名混乱而且很愚蠢,因为重点是模型对象几乎完全具有视图所需的数据。 我们将其保留在框架中(遵循WWDC 14“建立现代框架”的建议),以允许在共享扩展中更好地重用。
  3. 模型了解协议。 现在,我们正在为视图编写协议,以定义所需的数据,并将其移入框架。 荒谬,但确实完全不需要扩展。
  4. 协议扩展。 如果我们可以定义引用self的协议的默认实现,那么满足该协议的对象将访问它们的getter? 但是,虽然没有内联错误,但编译器(具体是链接器)不允许这样做,并引用“协议见证”,坚持认为Book仍未实现协议(我们保留扩展名以计算其不具备的属性) 。

这整个事情似乎很普通,只是说明类型已经满足了协议。 我们是否缺少任何简便的方法来执行此操作,或者是否有理由为什么/如何选择上述方法? 谢谢。

这对我有用,省去了实现声明,编译器仍然可以找出Book的符合性:

public struct Book {
    public let numberOfPages : Int
}

public protocol BookViewDataSource {
    var numberOfPages : Int { get }
}

extension Book : BookViewDataSource {
}

let x = Book(numberOfPages: 3)
print(x)

以上内容可在SwiftStub上使用,目前无法使用Mac!

如果您忽略扩展中的实现,则编译器应为您解决。 因此,应将其视为错误(链接器错误)。

您是否更新到Xcode 7 beta 5? 由于此版本解决了其中的一些问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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