Типизация, приводящая к изменению значений структуры (Swift) - PullRequest
0 голосов
/ 11 ноября 2018

После уменьшения массива структур, мое окно просмотра переменных показывает, что все значения в моей структуре сместились «вниз» (объясню через секунду). Но когда я печатаю (structName), значения в порядке. Однако, когда я запускаю проверку на равенство в структуре, она снова ведет себя так, как будто мои значения изменились.

Например, я пытаюсь понизить модель A до ModelProtocol. var m = Модель A и имеет значения {id: "1234", имя: "Cal"}. Когда я опущен, m теперь имеет значения {id: "\ 0 \ 0", name: "1234"}.

Фактический пример ниже:

Модели, которые я хочу понизить:

struct PrivateSchoolModel: Decodable, SchoolProtocol {
    var id: String
    var name: String
    var city: String
    var state: String
}
struct PublicSchoolModel: Decodable, SchoolProtocol {
    var id: String
    var name: String
    var city: String
    var state: String  
    var latitude: String
    var longitude: String
}

Протокол, который я хочу уменьшить до:

protocol SchoolProtocol {
    var id: String { get set }
    var name: String { get set }
    var city: String { get set }
    var state: String { get set }
    var longitude: Float { get set }
    var latitude: Float { get set }
}

extension SchoolProtocol {
    var longitude: Float {
        get { return -1.0 }
        set {}
    }
    var latitude: Float {
        get { return -1.0 }
        set {}
    }
}

понижающее приведение:

guard let downcastedArr = privateSchoolArray as? [SchoolProtocol] else { return [] }

Результат (элемент с индексом 0) или originalArr:

id = "1234"
name = "Leo High School"
city = "Bellview"
state = "WA"

Результат (элемент с индексом 0) downcastedArr:

id = "\0\0"
name = "1234"
city = "Leo High School"
state = "Bellview"

Но если я напечатаю (downcastArr [0]), он покажет:

id = "1234"
name = "Leo High School"
city = "Bellview"
state = "WA"

Но если я попробую originalArray [0] .id == downcastArr [0] .id, он вернет false

Мой код с проблемой:

class SchoolJSONHandler {
    private enum JSONFile: String {
        case publicSchool = "publicSchool"
        case privateSchool = "privateSchool"
    }

    private lazy var privateSchoolArray = getPrivateSchools()
    private lazy var publicSchoolArray = getPublicSchools()

    func getSchoolArray(sorted: Bool, filtered: Bool, by stateAbbreviation: String?) -> [SchoolProtocol] {
        var schools = combineArrays()

        if sorted {
            schools.sort(by: { $0.name < $1.name })
        }

        if filtered {
            guard let abbr = stateAbbreviation else { return [] }
            schools = schools.filter {
                return $0.state == abbr
            }
        }

        return schools
    }

    private func combineArrays() -> [SchoolProtocol] {
        // EVERYTHING IS FINE IN NEXT LINE
        let a = privateSchoolArray
        // PROBLEM OCCURS IN NEXT 2 LINES WHEN DOWNCASTING
        let b = privateSchoolArray as [SchoolProtocol]
        let c = publicSchoolArray as [SchoolProtocol]
        return b + c
    }

    private func getPublicSchools() -> [PublicSchoolModel] {
        guard let jsonData = getJSONData(from: .publicSchool) else { return [] }
        guard let schools = decode(jsonData: jsonData, using: [PublicSchoolModel].self) else { return [] }
        return schools
    }

    private func getPrivateSchools() -> [PrivateSchoolModel] {
        guard let jsonData = getJSONData(from: .privateSchool) else { return [] }
        guard let schools = decode(jsonData: jsonData, using: [PrivateSchoolModel].self) else { return [] }
        return schools
    }

    private func getJSONData(from resource: JSONFile) -> Data? {
        let url = Bundle.main.url(forResource: resource.rawValue, withExtension: "json")!
        do {
            let jsonData = try Data(contentsOf: url)

            return jsonData
        }
        catch {
            print(error)
        }

        return nil
    }

    private func decode<M: Decodable>(jsonData: Data, using modelType: M.Type) -> M? {
        do {
            //here dataResponse received from a network request
            let decoder = JSONDecoder()
            let model = try decoder.decode(modelType, from:
                jsonData) //Decode JSON Response Data

            return model
        } catch let parsingError {
            print("Error", parsingError)
        }

        return nil
    }
}

А потом он просто вызывается в другом классе schoolJSONHandler.getSchoolArray(sorted: true, filtered: true, by: "WA")

...