0

以下代码archivedTimes()在 swift4 中成功构建。它在安装了 ios10.3 的设备上运行良好。

typealias Time = CMTime
typealias Times = [Time]

static let times: Times = Array<Int64>.init(1...9).map({ CMTime.init(value: $0, timescale: 100) })

static func archivedTimes() -> Data {
    return archived(times: times)
}

static func archived(times: Times) -> Data {
    let values = times.map({ NSValue.init(time: $0) })
    return NSKeyedArchiver.archivedData(withRootObject: values) // ERROR here

    // -- ideally would instead be:
    // return NSKeyedArchiver.archivedData(withRootObject: times) 
    // -- but probably not compatible with ios 9.3
}

但是,在安装了 ios9.3 的设备上运行它时,它会崩溃说:

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“*** -[NSKeyedArchiver encodeValueOfObjCType:at:]:此归档程序无法编码结构”

我的猜测是,这可能与新的 Codable 协议和旧的 NSCoder 协议之间的某些冲突有关。但我不知道是什么!

请注意,该问题与数组无关。因为归档一个简单的 CMTime 也会导致这样的错误。但是,我这样发布它,因为归档 CMTime 数组最终是我的目标。

4

1 回答 1

0

我相信Codable协议仅在 ios10 中可用,因此在 ios9 上,CMTime不实现Codable.

因此,对于 ios9,我使用了 a 的包装类CMTime,它实现了NSCoding协议。

这可以通过 import AVFoundationwhich 声明扩展 toNSValue和 toNSCoder来进行编码CMTime

于是我选择了一个数组WrappedTime.init($0),而不是一个数组NSValue.init(time: $0)

class WrappedTime: NSObject, NSCoding {

    enum EncodeKey: String {
        case time = "time"
    }

    let time: CMTime

    // ...

    func encode(with aCoder: NSCoder) {
        aCoder.encode(time, forKey: EncodeKey.time.rawValue)
    }

    required init?(coder aDecoder: NSCoder) {
        time = aDecoder.decodeTime(forKey: EncodeKey.time.rawValue)
    }

    init(_ time: Time) {
        self.time = time
    }
}
于 2017-10-21T10:33:25.120 回答