swift - 协议类型“InheritingProtocol:协议”的值不能符合“协议”
问题描述
我有下面的代码,它的目标是abstraction
- 而不必在整个应用程序中Decodable
为 s 投射 s 。DataModel
我想用这些DataModel
s 来集中它们。这就是我现在走的路,我有点走投无路。
在这种配置中,代码告诉我ProfileResponseDelegate
不能符合ModelDelegate
when ProfileResponseDelegate
是 a protocol
,这是有道理的。
protocol ModelDelegate: class {
associatedtype DataType: Decodable
func didReceive(data: DataType)
}
class Model<Type, Delegate: ModelDelegate> where Type == Delegate.DataType {
var data: Type?
weak var delegate: Delegate?
func requestData() { return }
}
protocol ProfileResponseDelegate: ModelDelegate where DataType == ProfileResponse {}
//throws Value of protocol type 'ProfileResponseDelegate' cannot conform to 'ModelDelegate'; only struct/enum/class types can conform to protocols
class ProfileResponseModel: Model<ProfileResponse, ProfileResponseDelegate> {
override func requestData() {
guard let data = data else {
// go to api to get data
return
}
delegate?.didReceive(data: data)
}
}
class Controller: UIViewController, ProfileResponseDelegate {
let model = ProfileResponseModel()
override func viewDidLoad() {
super.viewDidLoad()
model.delegate = self
model.requestData()
}
func didReceive(data: ProfileResponse) {
//tell view code to update regarding data
}
}
当我更改ProfileResponseDelegate
为class
- 而不再是 a delegate
,但无论如何 - 代码不允许Controller
从两者继承UIViewController
并且ProfileResponseDelegate
推理 aclass
不能从多个class
es 继承。这又是有道理的。
class ProfileResponseDelegate: ModelDelegate {
typealias DataType = ProfileResponse
func didReceive(data: ProfileResponse) {
return
}
}
class Controller: UIViewController, ProfileResponseDelegate {
let model = ProfileResponseModel()
override func viewDidLoad() {
super.viewDidLoad()
model.delegate = self
model.requestData()
}
override func didReceive(data: ProfileResponse) {
//tell view code to update regarding data
}
}
关于第一个配置,我无法使其工作。但是对于第二个,当Controller
只是从它继承时ProfileResponseDelegate
就可以了。
我必须找到一种方法来完成这项工作——最好是第一个配置——并且需要你的建议。非常感谢提前。
更新
所以我associatedType
从ModelDelegate
和 中删除了ProfileResponseModel
。现在代码看起来像这样。
protocol ModelDelegate: class {
//associatedtype DataType: Decodable
func didReceive<T: Decodable>(data: T)
}
class Model<Type: Decodable> {
var data: Type?
weak var delegate: ModelDelegate?
func requestData() { return }
}
//protocol ProfileResponseDelegate: ModelDelegate where DataType == ProfileResponse {}
class ProfileResponseModel: Model<ProfileResponse> {
override func requestData() {
guard let data = data else {
// go to api to get data
return
}
delegate?.didReceive(data: data)
}
}
class Controller: UIViewController, ModelDelegate {
let model = ProfileResponseModel()
override func viewDidLoad() {
super.viewDidLoad()
model.delegate = self
model.requestData()
}
func didReceive<T>(data: T) where T : Decodable {
//I want this `data` to come as what it is.
if let response = data as? ProfileResponse {
print(type(of: response))
}
}
}
它的工作原理是这样的,但是我这样做的最终目的是不必将其投射data
到ProfileResponse
这里——在其他地方投射到其他Decodable
类型——。
解决方案
推荐阅读
- python - 如何将 python serial.readline() 数据中的数据读入字符串
- ibm-cloud - IBM Watson Assistant:Facebook 页面的多工作区?
- wordpress - 如果未使用,带有 wordpress 的 Gatsby 找不到 ACF 灵活内容字段
- r - 将列表作为列名给出时的格式更改
- mysql - 数据显示顺序
- teamcity - Team City 条件构建执行
- vba - 使用一个按钮,我只想为一个选定的单元格添加值
- java - 如何在方法调用之间交替?
- angular - 如何添加自定义角度材料垫错误
- c++ - 如何打印以pair(STL)为数据类型的set(STL)?