【发布时间】:2020-04-29 04:56:38
【问题描述】:
在我的应用程序中,几个控制器的代码结构非常相似,差异很小,所以为了优化我决定为这些控制器创建一个基础,并从基础继承每个特定的控制器。
我有一个发送网络请求和处理响应的函数,我把响应结构作为参数传递给这个函数,让函数返回一个现成的响应结构给我。每个这样的结构都是Decodable。
这种结构的一个例子:
struct APIAnswerUserActivity: Decodable {
let status: String
let code: Int?
let data: [UserActivity]?
let total: Int?
}
网络请求函数,Decodable.Protocol 类型的对象(结构)被接受为jsonType 参数:
public func networkRequest<T: Decodable> (
url: String,
timeout: Double = 30,
method: URLMethods = .GET,
data: [String : String]? = nil,
files: [URL]? = nil,
jsonType: T.Type,
success: @escaping (T) -> Void,
failure: @escaping (APIError) -> Void
) -> URLSessionDataTask { ... }
我在子控制器中通过覆盖覆盖了主控制器中的几个参数,其中一个参数应该是Decodable 类型的对象,以便通用函数正确接收数据。响应的 JSON 结构非常相似,但仍然略有不同,无法为它们创建通用结构,因为数据仍然略有不同。
如果在主控制器中这样做:
public var decodableType: Decodable.Type {
return APIAnswerUserActivity.self
}
这会起作用,并且可以重新定义类型,但是网络函数不接受这个,它需要Decodable.Protocol 对象。如果为变量decodableType指定了decodable.Protocol类型,那么就不能再添加APIAnswerUserActivity.self,在调用networkRequest函数时会悄悄接受。
遇到这种情况怎么办?我希望我能够正确、清楚地说明我的问题的本质。谢谢!
【问题讨论】:
-
"几个控制器的代码结构非常相似,差异很小,所以为了优化我决定为这些控制器创建一个基础,并从基础继承每个特定的控制器。"你称之为“控制器”的东西是什么?
-
@ElTomato,我有 UserActivityTableViewController、UserInvoicesTableViewController 等。在这些控制器中,无限滚动的方法用于在到达表格末尾时从网络加载数据。我创建了 InfinityScrollTableViewController 并在这个控制器上移动了所有常见的逻辑。在创建 UserActivity 控制器时,我会这样做: class UserActivityTableViewController: InfinityScrollTableViewController { ... }
-
@ElTomato 所有 UITableViewControllers 有 90% 的相似性,差异很小。我认为值得在 1 个控制器中实现所有相似之处,并从中继承每个特定的控制器并仅重新定义必要的方法。
-
在上面的部分源代码(构建 URLSessionDataTask 的代码)中查看由省略号 ({ ... }) 表示的代码会很有帮助。这大概就是问题所在。你能把它包括进来吗?
-
@iamtimmo,我在 InfinityScrollTableViewController 中有一个 getElementsFromNetwork 方法,这个方法运行 networkRequest 方法(我在上面留下了它的代码)。由于networkRequest方法需要Decodable类型作为必填参数,所以必须传递。我试图在 InfinityScrollTableViewController 中将 public var 创建为 Decodable.Protocol 类型并在附属 TableViewController 中覆盖它,但我得到编译错误。
标签: ios swift swift-protocols decodable swift-data