通过泛型来解析数据类型
在 Swift 中,当你尝试在子类中重写一个属性时,新属性的类型必须与父类中的原始属性类型兼容。在你提供的代码中,WADataBaseResponse 类定义了一个名为 data 的属性,其类型为 Any?。而在 WAUserBannerlistResponse 子类中,你尝试用更具体化的类型 [WAUserBannerModel]? 来重写它。Swift 不允许直接改变被重写的属性的类型,即使新的类型是旧类型的子类型,因为这会违反里氏替换原则(Liskov Substitution Principle),即子类应当可以替换父类而不影响程序的正确性。为了实现你的需求,你可以采取以下几种方法之一:
**泛型**:使父类变为泛型类,并指定 data 属性的类型参数。
**类型转换**:保持 data 属性为 Any? 类型,在需要时使用类型转换来获取具体的类型。
**添加新属性**:在子类中添加一个新的属性,用于存储特定类型的值,同时保留继承自父类的 data 属性。
下面是使用泛型的方式实现的例子:
class WADataBaseResponse<T>: WABaseObservableHandyJson {
var code: Int
var msg: String
var data: T?
var traceId: String
var timestamp: String
required init() {
code = 0
msg = ""
data = nil
traceId = ""
timestamp = ""
}
}
class WAUserBannerlistResponse: WADataBaseResponse<[WAUserBannerModel]> {
// 这里不需要重写 `data` 属性,因为它已经通过泛型指定了类型
}
在这个例子中,我们通过将 WADataBaseResponse 定义为泛型类,并将 data 属性的类型设置为泛型参数 T,从而解决了问题。这样,WAUserBannerlistResponse 就可以指定 data 的确切类型了。
一个网络请求的示例代码:
func loadHotBannerList() {
mockUserProvider.request(.userBannerList(category: 4)) { result in
if self.hotDataResetRefreshing {
self.hotDataResetRefreshing = false
}
switch result {
case .success(let response):
do {
if let jsonDict = try JSONSerialization.jsonObject(with: response.data, options: []) as? [String: Any] ,let responseData = WADataBaseResponse<[WAUserBannerModel]>.deserialize(
from: jsonDict
) {
if responseData.code == 200 {
self.bannerList = responseData.data ?? []
}
else {
// 这个地方到时候统一处理
}
}
else {
print("errorro : \(response.data)")
}
}
catch {
print("decode error : \(error.localizedDescription)")
}
case .failure(let error):
print("request failed with error : \(error.localizedDescription)")
}
}
}
主要是这里: WADataBaseResponse<[WAUserBannerModel]>.deserialize ,主要我们传入我们想要的数据类型就可以了,因为data可能是数组,也能是字典,传上对应的模型,就可以解决类型判断的问题了。
Last updated