简体   繁体   中英

Codable 'has no initializers' in Xcode 9.3 (Swift 4.1)

After updating to Xcode 9.3 (which uses Swift 4.1), the following issue was found:

  1. Create an empty project, add a new .swift file to it and create two new classes:

    创建为Codable类

     class CodableOne: Codable { let some: String } class CodableTwo: Codable { var some: String } 

    Build succeeds

  2. Add a new constant to CodableOne of type CodableTwo :

    为CodableOne添加了一个新常量

     class CodableOne: Codable { let some: String let another: CodableTwo } class CodableTwo: Codable { var some: String } 

    Build succeeds

  3. Now move class CodableTwo to another file (ViewController.swift, for example)

    CodableTwo移动到另一个文件

    Build fails .

Now there's an error, which won't go away. Codable classes should not require initializers (as demonstrated in previous steps).

Any ideas on what could be the problem behind this and how it could be resolved will be much appreciated!


PS Issue is not present in Xcode 9.2. Nor cleaning the project/build path, neither re-installing Xcode 9.3 helps.

As mentioned in the comments , I had to do two things:

  1. changing Compilation Mode to Whole Module inside Project settings/Build Settings :

    编译模式设置为整个模块

  2. reordering the files under Project settings/Build Phases/Compile Sources . Specifically, I brought the files that had an error to the front of the list.

    Protip: if you search for the name of the file and there is more than one result, dragging the file to the top in that smaller list will still bring it to the front.

This is a bug in the Swift 4.1 compiler. To work around it, either do the steps outlined in the4kman's answer, or simply change let to var in your declaration, as such:

class C1 : Decodable { 
  let str: String 
  // error: Class 'C1' has no initializers - if class C's `c1` is a let constant. 
}

class C : Decodable {
  var c1: C1 // << Change to `var`, compilation succeeds.
}

Workaround courtesy of Apples Swift engineers .

If neither this nor the4kmans answer helps, you can add another init to the models who won't compile. If your classes have tons of variables, just crash the init to satisy the compiler. The Codable initializer will still be synthesized.

class C1: Decodable {
    let str: String

    @available(*, deprecated, message: "Do not use.")
    private init() {
        fatalError("Swift 4.1") 
    }
}

我有这个问题,即使我的所有类都在同一个文件中,使用更深层次的结构似乎也可以工作

try to give your variable an initial value like this (change your code to this)

class CodableOne: Codable{

    var some = ""

}

class CodableTwo: Codable{

    var some = ""

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM