在 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 值?
Xcode 9.3(Swift 4.1)中的 Codable '没有初始化器'
如何在 Swift 中使用 Codable 转换带有可选小数秒的日期字符串?