【问题标题】:fatal error: unexpectedly found nil while unwrapping an Optional value in Swift 3致命错误:在 Swift 3 中展开可选值时意外发现 nil
【发布时间】:2016-10-26 21:24:16
【问题描述】:

这个结构在 swift 2 中工作

我有一个这样的 Swift 3 结构。

let tempContacts =  NSMutableArray()
let arrayOfArray =  NSMutableArray()

我在这个 for 循环中编码了 Person 对象

    for person in tempContacts as! [Person] {

        let encodedObject: Data = NSKeyedArchiver.archivedData(withRootObject: person) as Data
        arrayOfArray.add(encodedObject)

    }

我已经解码了这个for循环中的数据

let tempContacts2 = NSMutableArray()
   for data in arrayOfArray {

        let person: Person = NSKeyedUnarchiver.unarchiveObject(with: data as! Data) as! Person
        tempContacts2.add(person)   

    }

但 unarchiveObject 总是返回 nil 值

【问题讨论】:

  • 您的Person 对象是否符合NSCoding 协议?
  • 是的,我在我的 Person 类中使用了 NScoding 协议
  • 你为什么在 Swift 中使用一个完全不相关的类型,比如NSMutableArray,而不是一个 Swift Array,在解码部分使用实际类型为[Person]?您正在丢弃作为 Swift 基本语义之一的类型信息。

标签: ios swift swift3


【解决方案1】:

首先你的模型类应该符合 NSCoder 协议。剩下的很简单,不需要将每个对象的归档结果存储在一个数组中,您可以像这样将初始数组直接传递给 NSKeyedArchiver:

class Person: NSObject, NSCoding {
    var name = ""

    init(name: String) {
        self.name = name
    }

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

    func encode(with coder: NSCoder) {
        coder.encode(self.name, forKey: "name")
    }
}

let tempContacts = [Person(name: "John"), Person(name: "Mary")]

let encodedObjects = NSKeyedArchiver.archivedData(withRootObject: tempContacts)
let decodedObjects = NSKeyedUnarchiver.unarchiveObject(with: encodedObjects)

作为一个侧面注意:如果在您的模型类中正确实现了 NSCoder 合规性,您当然也可以使用您的归档/取消归档单个对象的方式。所以你的原始代码也可以工作,只是做了一些小的调整:

for person in tempContacts {
    let encodedObject = NSKeyedArchiver.archivedData(withRootObject: person)
    arrayOfArray.add(encodedObject)
}

var tempContacts2 = [Person]()
for data in arrayOfArray {
    let person: Person = NSKeyedUnarchiver.unarchiveObject(with: data as! Data) as! Person
    tempContacts2.append(person)
} 

注意 2:如果您绝对想使用 NSMutableArrays 也可以,只需像这样定义 tempContacts

let tempContacts =  NSMutableArray(array: [Person(name: "John"), Person(name: "Mary")])

其余的工作没有变化。

注意 3:它曾经在 Swift 2 中工作而在 Swift 3 中不再工作的原因是 NSCoder 方法 func encode(with coder:) 的签名在 Swift 3 中发生了变化。

【讨论】:

  • 对不起,我的 tempContacts 不是 [Person] arrye 使用的
  • 但实际上 tempContacts 是 NSMutableArray()
  • 让 person: Person = Person(name: "John")
  • tempContact.add(person)
  • 是的,它也适用于 NSMutableArray,请看我的第二条笔记。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-30
  • 2015-03-04
  • 1970-01-01
相关资源
最近更新 更多