Codable 'не имеет инициализаторов' в Xcode 9.3 (Swift 4.1)

После обновления до Xcode 9.3 (который использует Swift 4.1) была обнаружена следующая проблема:

  1. Создайте пустой проект, добавьте к нему новый файл.swift и создайте два новых класса:

    Created to Codable classes

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

    Сборка завершается

  2. Добавьте новую константу в CodableOne типа CodableTwo:

    Added a new constant to CodableOne

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

    Сборка завершается

  3. Теперь переместите класс CodableTwo в другой файл (например, ViewController.swift)

    CodableTwo moved to another file

    Сбой сборки.

Теперь есть ошибка, которая не исчезнет. Codable классы не должны требовать инициализаторы (как показано на предыдущих шагах).

Любые идеи о том, что может быть проблемой этого и как его можно решить, будут высоко оценены!


Проблема PS отсутствует в Xcode 9.2. Не очищая путь проекта/сборки, ни повторная установка Xcode 9.3 не помогает.

Ответы

Ответ 1

Как упоминалось в комментариях, мне пришлось сделать две вещи:

  1. изменение режима компиляции на весь модуль внутри параметров проекта/настройки сборки:

    Compilation Mode set to Whole Module

  2. переупорядочение файлов в разделе " Настройки проекта"/"Сформировать фазы/Скомпилировать источники". В частности, я привел файлы, у которых была ошибка перед списком.

    Protip: если вы ищете имя файла и есть более одного результата, перетаскивание файла вверху в этом меньшем списке по-прежнему приведет его к фронту.

Ответ 2

Это ошибка в компиляторе Swift 4.1. Чтобы обойти это, выполните шаги, описанные в ответе4kman, или просто измените let на var в своем объявлении:

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

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

Обходное решение предоставлено инженерами Apple Swift.

Если ни ответ ни на этот вопрос, ни на вопрос 4kmans не помогут, вы можете добавить еще один init для моделей, которые не будут компилироваться. Если у ваших классов есть множество переменных, просто скомпрометируйте init чтобы удовлетворить компилятор. Инициализатор Codable все еще будет синтезирован.

class C1: Decodable {
    let str: String

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

Ответ 3

У меня была эта проблема, хотя все мои классы были в одном файле, используя структуры для более глубоких, похоже, работает

Ответ 4

попробуйте указать переменную начальное значение (измените код на это)

class CodableOne: Codable{

    var some = ""

}

class CodableTwo: Codable{

    var some = ""

}