在初始化所有存储的属性之前,由于自我导致的自定义解码器错误

时间:2020-06-27 09:44:24

标签: swift compiler-errors decodable

我有以下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)
    }
}

以上内容无法编译,因为在所有存储的属性初始化之前,我试图同时使用sortcompute(from:)

'self'在初始化所有存储的属性之前使用。

要解决此问题,我确实可以在init(from:)解码器内的two方法内移动逻辑。我会避免这样做,因为VideoResponse可以用作普通的struct

extension VideoReponse {
    init(videos: [Videos]) { 
        // same setup here...
    }
}

关于如何解决此问题以避免重复代码的任何想法?

2 个答案:

答案 0 :(得分:2)

我的建议:

  1. lastVideos声明为懒惰
  2. 使用内置API排序

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 computeLastVideosself 根本不会访问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

但是如果sortcomputerLastVideos可以访问self,则您不走运,必须将videos设为非{ {1}},然后先进行初始化,然后再进行更改。您无法向Swift保证letsort仅访问computeLastVideos的初始化部分