首页 > 解决方案 > 协议类型“InheritingProtocol:协议”的值不能符合“协议”

问题描述

我有下面的代码,它的目标是abstraction- 而不必在整个应用程序中Decodable为 s 投射 s 。DataModel我想用这些DataModels 来集中它们。这就是我现在走的路,我有点走投无路。

在这种配置中,代码告诉我ProfileResponseDelegate不能符合ModelDelegatewhen 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
    }
}

当我更改ProfileResponseDelegateclass- 而不再是 a delegate,但无论如何 - 代码不允许Controller从两者继承UIViewController并且ProfileResponseDelegate推理 aclass不能从多个classes 继承。这又是有道理的。

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就可以了。

我必须找到一种方法来完成这项工作——最好是第一个配置——并且需要你的建议。非常感谢提前。

更新

所以我associatedTypeModelDelegate和 中删除了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))
        }
    }
}

它的工作原理是这样的,但是我这样做的最终目的是不必将其投射dataProfileResponse这里——在其他地方投射到其他Decodable类型——。

标签: swiftgenericsmodel-view-controllerprotocolsdelegation

解决方案


推荐阅读