Xcode 在Swift中使用结构时,如何简洁地定义模型对象?

Xcode 在Swift中使用结构时,如何简洁地定义模型对象?,xcode,swift,struct,model,Xcode,Swift,Struct,Model,我在某个地方读到,在使用Swift传递模型数据时使用结构是最佳实践 我一直在这样做,但我一直在想,在创建大型(且不断增长的)用户数据对象方面,我是否可以做些什么: struct UserAccount { var id: String? let authId: String let emailAddress: String let mobilePhoneNumber: String let firstName: String let last

我在某个地方读到,在使用Swift传递模型数据时使用结构是最佳实践

我一直在这样做,但我一直在想,在创建大型(且不断增长的)用户数据对象方面,我是否可以做些什么:

struct UserAccount {

    var id: String?
    let authId: String

    let emailAddress: String
    let mobilePhoneNumber: String

    let firstName: String
    let lastName: String

    let countryCode: String
    let homepageUrl: String
    let tagline: String

    let pictureUrl: String

    let accountState: AccountState = .NoAccount

    // ... 
}
这或多或少是我在创建用户帐户时使用的方法,但后来不得不在代码中实例化巨大的对象,这会让我觉得既麻烦又错误。我正在使用解析JSON响应,但必须单独实例化模型,如下所示:

let id = jsonData["id"].string!
let authId = jsonData["authId"].string!
let emailAddress = jsonData["emailAddress"].string!
let mobilePhoneNumber = jsonData["mobilePhoneNumber"].string!
let firstName = jsonData["firstName"].string!
let lastName = jsonData["lastName"].string!
let countryCode = jsonData["countryCode"].string!
let homepageUrl = jsonData["homepageUrl"].string!
let tagline = jsonData["tagline"].string!
let pictureUrl = jsonData["pictureUrl"].string!
let accountState = convertAccountStateStringToEnum(jsonData["accountState"].string!)


let userAccount = UserAccount(
    id: id,
    authId: authId,
    emailAddress: emailAddress,
    mobilePhoneNumber: mobilePhoneNumber,
    firstName: firstName,
    lastName: lastName,
    countryCode: countryCode,
    homePageUrl: homepageUrl,
    tagline: tagline,
    pictureUrl: pictureUrl,
    accountState: accountState
)
上面我在实例化结构之前实例化了变量,这可能看起来很荒谬,但我这样做的原因是,当IDE从结构中给我类型强制错误时,很难理解什么是错误的,因此这允许我在进行模型更改时更快地对其进行故障排除。对此有何想法?

我的问题:

稍后,该用户对象可能在服务器端包含更多的数据,用50多行代码实例化使用模型似乎是个坏主意,因此:

  • 有没有以更简单的方式创建结构的解决方案?这个图案有名字吗
  • 我应该创建与特定任务相关的用户模型吗?例如,用于获取或放置配置文件的UserAccount模型可能与用于身份验证、获取用户设置或列出我的服务上最流行的帐户的模型不同
  • 人们是否只是保持原样,定义映射器以避免冗余?如果是的话,这方面的好例子是什么

  • 谢谢。

    当面对这个问题时,我会为接受JSON数据的模型构建另一个初始值设定项:

    struct UserAccount {
        // ...
        init(jsValue: JSValue) {
            id = jsonData["id"].string!
            authId = jsonData["authId"].string!
            emailAddress = jsonData["emailAddress"].string!
            mobilePhoneNumber = jsonData["mobilePhoneNumber"].string!
            firstName = jsonData["firstName"].string!
            lastName = jsonData["lastName"].string!
            countryCode = jsonData["countryCode"].string!
            homepageUrl = jsonData["homepageUrl"].string!
            tagline = jsonData["tagline"].string!
            pictureUrl = jsonData["pictureUrl"].string!
            accountState = convertAccountStateStringToEnum(jsonData["accountState"].string!)
        }
    }
    
    let userAccount = UserAccount(jsValue: jsonData)
    
    然后,您只需从JSON数据创建新的
    UserAccount
    实例:

    struct UserAccount {
        // ...
        init(jsValue: JSValue) {
            id = jsonData["id"].string!
            authId = jsonData["authId"].string!
            emailAddress = jsonData["emailAddress"].string!
            mobilePhoneNumber = jsonData["mobilePhoneNumber"].string!
            firstName = jsonData["firstName"].string!
            lastName = jsonData["lastName"].string!
            countryCode = jsonData["countryCode"].string!
            homepageUrl = jsonData["homepageUrl"].string!
            tagline = jsonData["tagline"].string!
            pictureUrl = jsonData["pictureUrl"].string!
            accountState = convertAccountStateStringToEnum(jsonData["accountState"].string!)
        }
    }
    
    let userAccount = UserAccount(jsValue: jsonData)
    
    一些想法:

    • 您能否分享一个参考,它建议在传递模型数据时使用结构而不是类的最佳实践?我原以为通过值传递结构(尤其是大结构)比通过引用传递类实例效率低

      请参见在类和结构之间选择,其中建议您在以下情况下使用结构:

      • 该结构的主要目的是封装一些相对简单的数据值

      • 在指定或传递该结构的实例时,可以合理地预期封装的值将被复制而不是引用

      • 结构存储的任何属性本身都是值类型,也希望复制而不是引用

      • 结构不需要继承其他现有类型的属性或行为

      您的用户对象似乎不符合此条件。我认为课堂教学法更符合逻辑

    • 顺便说一句,如果使用类,您还可以简化代码以实例化符合KVO的对象。例如,您可以遍历一个键名数组,从JSON中获取与每个键名关联的值,然后使用
      setValue:forKey:
      设置该特定键的对象属性

      有关KVO法规遵从性的更多信息,请参阅。有关如何使Swift对象符合KVO的更多信息,请参阅的“关键值观察”部分

    • 就不同任务的不同用户模型而言,这对我来说没有意义。您可能有不同的对象用于不同的功能目的(例如帐户/身份验证对象),这些对象可能引用用户对象,但使用不同类型的用户类/结构似乎没有意义