在 Swift 中实例化一个新的 Codable 对象的最简单方法是啥?

Posted

技术标签:

【中文标题】在 Swift 中实例化一个新的 Codable 对象的最简单方法是啥?【英文标题】:What is the simplest way to instantiate a new Codable object in Swift?在 Swift 中实例化一个新的 Codable 对象的最简单方法是什么? 【发布时间】:2019-01-22 05:40:38 【问题描述】:

我有一个 Codable 类:

class Task: Codable 
    var name: String

当我尝试实例化它时:

let newTask = Task()
allTasks.append(newTask)

它给了我错误:

调用中的参数“from”缺少参数

我想要的只是将一个新对象(newTask)插入到一个数组中。最简单的方法是什么?

【问题讨论】:

如果您不使用任何编码键,为什么要使用可编码?? 你有什么理由不接受我的回答吗? 【参考方案1】:

你可以从 NSObject 继承初始化器:

class Task: NSObject, Codable 
    var name: String = ""


let newTask = Task()

如果您不想继承 NSObject,那么只需创建自己的初始化程序:

class Task: Codable 
    var name: String?

    init() 

    

如果您不想让name 成为可选(或将其设置为默认值),则必须在 init() 中对其进行初始化,例如:

class Task: Codable 
    var name: String

    init(withName name: String) 
        self.name = name
    

let newTask = Task(withName: "ikevin8me")

【讨论】:

好的,请查看编辑后的回复。 name 变量需要一个默认值。否则,在分配 self 之前它是未启动的。 好的,这使它工作,但这确实不是最好的解决方案。它不必要地带来了NSObject 和所有的Objective-C 包袱。并且默认 name 为空字符串是非常非 Swifty 的。 然后编写你自己的初始化器。 我添加了一个没有继承NSObject的例子。 如果你不想要一个空字符串,你可以让这个字符串是可选的,或者你必须在 init() 中初始化它。我更改了第二个示例以使其成为可选。【参考方案2】:

另一个解决方案是使用struct

struct Task: Codable 
    var name: String


let task = Task(name: "myname")

【讨论】:

【参考方案3】:

您的 Task 类没有提供自己的初始化程序,因此它获取在 Codable 协议中定义的初始化程序(它从 Decodable 协议中获得)。

要么添加您自己的显式init,它采用name 参数,要么将您的类更改为结构。无论哪种方式,您都需要通过传入名称值来创建Task,以便可以初始化name 属性。

这些都没有解决您发布的代码没有使用Codable 的事实,因此您的类(或结构)可能不需要符合Codable

【讨论】:

【参考方案4】:

Task 类不提供任何初始化器来初始化对象,这就是它从 Codable 协议获取初始化器的原因,提供您自己的初始化器来初始化对象。

用法:

1.带类

class Task: Codable 
    var name: String
    init(_ name : String) 
        self.name = name
    


var task = Task("Jarvis")

2.带结构:

struct Task: Codable 
    var name: String


let task = Task(name: "jarvis")

【讨论】:

为什么要隐式解包name 属性?不要不必要地这样做。 @rmaddy 我希望它能正确初始化。 已更新...你能说出为什么你这么害怕'!' ;) 我不怕。我向您指出,当它不合适时,您不应该使用它。这里不需要。 @JarvisTheAvenger 有a few very specific situations where you should use implicitly unwrapped optionals。大多数情况下,要么是不必要的,要么可能会导致您的应用崩溃,这似乎是“害怕”的合理事情。【参考方案5】:

我不会为属性分配默认值,而是实现预期的 init 方法和不带任何参数的便利变体,或者具有创建“空”任务的工厂方法

这是两个选项的代码

class Task: Codable 
    var name: String

    init(_ name: String) 
        self.name = name
    

    convenience init() 
        self.init("")
    

    static func emptyTask() -> Task 
        return Task("")
    

【讨论】:

以上是关于在 Swift 中实例化一个新的 Codable 对象的最简单方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Swift Codable - 如何编码和解码字符串化的 JSON 值?

Swift4 中的 Codable 和 XMLParser

Xcode 9.3(Swift 4.1)中的 Codable '没有初始化器'

如何在 Swift 中使用 Codable 转换带有可选小数秒的日期字符串?

如何在 Core Data 中使用 swift 4 Codable?

如何在 Core Data 中使用 swift 4 Codable?