协议中的默认初始化程序需要不需要的可变属性

时间:2017-03-29 14:23:42

标签: ios json swift swift3 protocols

在Swift 3中想象一下,您希望您的模型在整个应用中都是值类型(结构)。但您也希望使用Core Data / Realm持久化所述模型,这需要您创建类。然后你可以使用JSON将结构转换为类和反之亦然(这需要结构和类来支持JSON反序列化和序列化)。

如果你不必在两个地方编写JSON反序列化(类似于序列化,但我在这里专注于反序列化),那么它是不是很整洁,但是使用put deserialization in a 协议,您的结构和类都使用。

使用结构我们希望我们的JSON模型具有不可变字段,因此所有属性都是Mat twoviewcloud = readCloud("pointcloud.ply"); writeCloud("trial.ply", twoviewcloud, noArray(), noArray(), false); 常量。但是使用反序列化的let实现不允许使用此AFAIK。

下面的代码示例,但它很难看,因为代码中的注释中标记了所有不需要的要求(UR)。

protocol

是否有另一种方法可以实现这一目标,同时减少不必要的需求量?或者使用零UR的最佳解决方案?

1 个答案:

答案 0 :(得分:0)

感谢@hamish所指出的,最好的解决方案是(struct JSONprotocol JSONDeserializable保持相同的问题)。这不是一个完美的解决方案,因为您必须实现该类的初始化程序。整洁的部分是你不必为结构实现任何初始化器,因为它有一个隐式的初始化器。

protocol UserModel: JSONDeserializable {
    var username: String { get }
    var firstname: String { get }
    var country: String { get }
    init(
        username: String,
        firstname: String,
        country: String
    )
}

extension UserModel {
    init(json: JSON) throws {
        self.init(
            username: try json.value("username"),
            firstname: try json.value("firstname"),
            country: try json.value("country")
        )
    }
}

struct UserStruct: UserModel {
    let username: String
    let firstname: String
    let country: String
    // struct has default initializer
}

final class UserClass: UserModel {
    let username: String
    let firstname: String
    let country: String
    init(
        username: String,
        firstname: String,
        country: String
        ) {
        self.username = username
        self.firstname = firstname
        self.country = country
    }
}

let json: JSON = JSON(json: [
    "username": "Sajjon",
    "firstname": "Alexander",
    "country": "Sweden"
    ])
let u1 = try UserStruct(json: json)
let u2 = try UserClass(json: json)
print(u1.username) // prints "Sajjon"
print(u2.username) // prints "Sajjon"