0

在向下转换结构数组后,我的变量视图窗口显示我的结构中的所有值都已“向下”移动(稍后将解释)。但是当我打印(structName)时,这些值很好。但是,当我对结构运行相等检查时,它再次表现得好像我的值发生了变化。

例如,我试图将模型 A 向下转换为 ModelProtocol。var m = 模型 A 并具有值 {id: "1234", name: "Cal"}。当我沮丧时,m 现在有值 { id:"\0\0", name:"1234" }。

在向下转换结构数组后,我的变量视图窗口显示我的结构中的所有值都已“向下”移动(稍后将解释)。但是当我打印(structName)时,这些值很好。但是,当我对结构运行相等检查时,它再次表现得好像我的值发生了变化。

例如,我试图将模型 A 向下转换为 ModelProtocol。var m = 模型 A 并具有值 {id: "1234", name: "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"

downcastedArr 的结果(索引 0 处的项目):

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")

4

0 回答 0