gpt4 book ai didi

ios - init的可选性?(coder :) vs init(coder:). 如果nil怎么办?

转载 作者:可可西里 更新时间:2023-11-01 02:04:52 26 4
gpt4 key购买 nike

NSCoding 需要 init(coder:),但也有此方法的可选版本 init?(coder:)

如果返回 nil,具体应该怎么办?这甚至是一个问题吗?

假设您正在使用 init(coder:) 初始化大型对象层次结构,每个对象的子对象本身都使用 init?(coder:) 进行初始化。如果其中一个对象是 nil,应用程序不会崩溃吗?父对象不期望一个 nil 子对象。

“init nil”到底是什么意思?

  class Parent: NSCoding {

var children: [Child]

required init?(coder aDecoder: NSCoder) {
guard let children = aDecoder.decodeObject(forKey: "children") as? [Child] else { return nil }
self.children = children
}

}

class Child: NSCoding {
var name: String

required init?(coder aDecoder: NSCoder) {
guard let name = aDecoder.decodeObject(forKey: "name") as? String else { return nil }
self.name = name
}

}

一种策略是简单地返回一个新实例,而不是简单地返回 nil。数据会丢失,但应用程序会运行。

最佳答案

最好不要返回nil

作为我在 Xcode 8.3.2 (8E2002) 中的测试,在 init(coder:) 中返回 nil 导致 NSKeyedUnarchiver.unarchiveObject 崩溃或返回意外结果。

准备一个为“test2”编码错误数据类型的类:

class MyClass: NSObject, NSCoding {
var x: String

init(_ x: String) {
self.x = x
}

required init?(coder aDecoder: NSCoder) {
guard let x = aDecoder.decodeObject(forKey: "x") as? String else {
return nil
}
self.x = x
}

func encode(with aCoder: NSCoder) {
if x == "test2" {
aCoder.encode(Int(4), forKey: "x")
} else {
aCoder.encode(x, forKey: "x")
}
}
}

TestCaseA:归档一个包含上面MyClass的字典,然后取消归档。

结果:NSKeyedUnarchiver.unarchiveObject 崩溃。

    let encodedData = NSKeyedArchiver.archivedData(withRootObject: [
"k1":MyClass("test1"),
"k2":MyClass("test2"),
"k3":"normal things"
])
UserDefaults.standard.set(encodedData, forKey: "xx")


if let data = UserDefaults.standard.data(forKey: "xx"),
let _data = NSKeyedUnarchiver.unarchiveObject(with: data) {
if let dict = _data as? [String:Any] {
debugPrint(dict.count)
}
}

TestCaseB:归档一个包含上面MyClass的数组,然后取消归档。

结果:返回一个空数组(但预期是一个包含 1 个元素的数组)

    let encodedData = NSKeyedArchiver.archivedData(withRootObject: [
MyClass("test1"),
MyClass("test2")
])
UserDefaults.standard.set(encodedData, forKey: "xx")


if let data = UserDefaults.standard.data(forKey: "xx"),
let _data = NSKeyedUnarchiver.unarchiveObject(with: data) {
if let dict = _data as? [Any] {
debugPrint(dict.count)
}
}

关于ios - init的可选性?(coder :) vs init(coder:). 如果nil怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43906382/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com