gpt4 book ai didi

ios - 无法满足协议(protocol)(具有关联类型)的一致性

转载 作者:搜寻专家 更新时间:2023-11-01 06:53:00 24 4
gpt4 key购买 nike

我在我的新项目中使用 CleanSWift,但我发现它太冗长了。为了自动化一些基本的东西,我编写了以下工具(简化):

// MARK: - Presenter

protocol Presenter {
associatedtype DisplayLogic
var viewController: DisplayLogic? { get set }
}

protocol PresentationLogic {
func show(_ error: Error)
}

extension PresentationLogic where Self: Presenter, Self.DisplayLogic: DefaultDisplayLogic {
func show(_ error: Error) {
}
}

// MARK: - Display logic

protocol DefaultDisplayLogic: class {
// func present(_ error: Error)
}

protocol TableViewDisplayLogic: DefaultDisplayLogic {
// func reloadTableView(with sections: [Section])
}

当我尝试实现上面的代码时,泛型似乎被破坏了。我收到一条错误消息“类型‘MyPresenter’不符合协议(protocol)‘PresentationLogic’”。但是,我觉得一切都很好。

// MARK: - Controller

protocol MyDisplayLogic: DefaultDisplayLogic {
}

class MyViewController: UIViewController, MyDisplayLogic {
}

// MARK: - Interactor

protocol MyBusinessLogic {
}

class MyInteractor: MyBusinessLogic {
var presenter: MyPresentationLogic?

func test() {
presenter?.show(TestError.unknown)
}
}

// MARK: - Presenter

protocol MyPresentationLogic: PresentationLogic {
}

class MyPresenter: Presenter, MyPresentationLogic {
weak var viewController: MyDisplayLogic? // ** Here I get the error. **
}

有什么想法吗?谢谢。

最佳答案

目前MyPresenter不满足PresentationLogic扩展where子句的要求,所以不能使用show( _:)。具体来说,它没有通过 Self.DisplayLogic: DefaultDisplayLogic 的测试。因此,它不符合 PresentationLogic,因此它也不符合继承自 PresentationLogicMyPresentationLogic

但为什么不呢?我认为这是由 Swift 的工作方式引起的:协议(protocol)无法符合自身。在MyPresenter中,Self.DisplayLogicMyDisplayLogic。尽管它是 DefaultDisplayLogic 的后代协议(protocol),但它似乎仍充当“试图符合自身的协议(protocol)”,因此它不起作用。

为了演示这一点,您可以将 weak var viewController: MyDisplayLogic? 替换为 weak var viewController: MyViewController,错误就会消失,因为它是一个具体类型符合 DefaultDisplayLogic。此外,如果您将 where 子句中的 Self.DisplayLogic: DefaultDisplayLogic 更改为 Self.DisplayLogic == MyDisplayLogic,错误将消失,因为您需要特定类型而不是一致性。

在您的情况下,一个可能的解决方案是使 MyPresenter 成为通用类。例如:

class MyPresenter<ConcreteDisplayLogic: DefaultDisplayLogic>: Presenter, MyPresentationLogic {
weak var viewController: ConcreteDisplayLogic?
}

这将允许您对 show(_:) 的默认实现使用相同的 where 子句约束,同时提供 MyPresenter 的类型安全的通用实现.

这种方法有一个局限性:您不能为 MyPresenter 的单个实例更改 viewController 值的类型。

关于ios - 无法满足协议(protocol)(具有关联类型)的一致性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55872244/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com