我有以下Decodable
模型:
struct VideoResponse: Decodable {
let videos: [Video]
let lastVideos: [Video]
enum CodingKeys: String, CodingKey {
case videos
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let videos = try container.decode([Video].self, forKey: .videos)
self.videos = sort(videos)
self.lastVideos = computeLastVideos(from: self.videos)
}
}
以上内容无法编译,因为在所有存储的属性初始化之前,我试图同时使用sort
和compute(from:)
。
'self'在初始化所有存储的属性之前使用。
要解决此问题,我确实可以在init(from:)
解码器内的two方法内移动逻辑。我会避免这样做,因为VideoResponse
可以用作普通的struct
。
extension VideoReponse {
init(videos: [Videos]) {
// same setup here...
}
}
关于如何解决此问题以避免重复代码的任何想法?
答案 0 :(得分:2)
我的建议:
lastVideos
声明为懒惰struct VideoResponse: Decodable {
let videos: [Video]
lazy var lastVideos : [Video] = {
return self.computeLastVideos(from: self.videos)
}()
enum CodingKeys: String, CodingKey { case videos }
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.videos = try container.decode([Video].self, forKey: .videos).sorted(by: { ... })
}
}
答案 1 :(得分:2)
您无法在所有存储属性都初始化之前在self
上调用方法,因为这些方法可能会访问未初始化的属性(另请参见this answer of mine),然后谁知道会发生什么?您可以通过输入单词sort
来告诉Swift computeLastVideos
和self
根本不会访问static
,
static func sort(_ videos: [Video]) -> [Video] { ... }
static func computeLastVideos(from videos: [Video]) -> [Video] { ... }
您还必须首先将排序后的视频放入临时变量sortedVideos
中,因为您无法访问self.videos
:
let container = try decoder.container(keyedBy: CodingKeys.self)
let videos = try container.decode([Video].self, forKey: .videos)
let sortedVideos = VideoResponse.sort(videos)
self.lastVideos = VideoResponse.computeLastVideos(from: sortedVideos)
self.videos = sortedVideos
但是如果sort
和computerLastVideos
可以访问self
,则您不走运,必须将videos
设为非{ {1}},然后先进行初始化,然后再进行更改。您无法向Swift保证let
和sort
仅访问computeLastVideos
的初始化部分。