gpt4 book ai didi

swift - 检查两个对象是否实现了 Swift 协议(protocol)及其关联类型

转载 作者:搜寻专家 更新时间:2023-11-01 05:34:49 25 4
gpt4 key购买 nike

我有一个 Swift 3 项目,我在其中声明一个具有关联类型的协议(protocol),如下所示:

protocol ViewModelContainer {
associatedtype ViewModelType
var viewModel: ViewModelType! { get set }
}

我想检查两个对象是否实现了 ViewModelContainer 及其关联类型 ViewModelType 以“通用”方式进行分配。

理想情况下我想做这样的事情:

if let container = container as? ViewModelContainer, let model = model as? container.ViewModelType {
container.viewModel = model
}

但我无法将 container 转换为 ViewModelContainer:

Protocol 'ViewModelContainer' can only be used as a generic constraint because it has Self or associated type requirements


我目前的解决方法是直接回退到特定的类及其关联类型,但这使我的代码非常冗长且容易出错:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? MediaPlaySelectionViewController, let vm = sender as? MediaPlaySelectionViewModel {
vc.viewModel = vm
}
if let vc = segue.destination as? SearchResultsViewController, let vm = sender as? SearchResultsViewModel {
vc.viewModel = vm
}
if let vc = segue.destination as? ReviewDetailsViewController, let vm = sender as? ReviewDetailsViewModel {
vc.viewModel = vm
}
if let vc = segue.destination as? ReviewComposerViewController, let vm = sender as? ReviewComposerViewModel {
vc.viewModel = vm
}
}

我尝试使用通用的 UIViewController,但由于 Objective-C doesn't recognize generic Swift classes 而卡住了因此不能在 Storyboard 中使用。

最佳答案

这比我预期的要棘手(所以我删除了我之前的帖子以避免混淆)但我相信这对你有用:

 protocol ViewModelContainerVC 
{
mutating func setModel(_ :Any)
}

protocol ViewModelContainer:class,ViewModelContainerVC
{
associatedtype ViewModelType
var viewModel: ViewModelType! { get set }
}

extension ViewModelContainer
{
mutating func setModel(_ model:Any)
{ if model is ViewModelType { viewModel = model as! ViewModelType } }
}

然后您可以使用 ViewModelContainerVC 进行类型转换和赋值:

 if let container = container as? ViewModelContainerVC 
{
container.setModel(model)
}

[编辑] 以供将来引用,这里有同样的事情,返回 Bool 以实现类型兼容性:

 protocol ViewModelContainerVC 
{
@discardableResult mutating func setModel(_ :Any) -> Bool
}

extension ViewModelContainer
{
@discardableResult mutating func setModel(_ model:Any) -> Bool
{
if let validModel = model as? ViewModelType
{ viewModel = validModel; return true }
return false
}
}

这将允许组合条件:

 if var container = container as? ViewModelContainerVC,
container.setModel(model)
{ ... }

关于swift - 检查两个对象是否实现了 Swift 协议(protocol)及其关联类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42654473/

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