Swift 和 NSCoding:编码符合 class-only 协议的对象数组

Swift and NSCoding: Encoding an array of objects conforming to a class-only protocol

我有一个 class、StandardObject,它符合协议 Object。另一个 class、ObjectManager 有一个名为 objects 的 属性,它是一个包含 Object 实例的数组。 StandardObjectObjectManager 都是 NSObject 的子 class 并且符合 NSCoding.

当我尝试在 encodeWithCoder: 中编码 ObjectManagerobjects 属性 时,我收到一个错误:

cannot convert value of type '[Object]' to expected argument type 'AnyObject?'

这是我的代码:

ObjectManager:

class ObjectManager: NSObject, NSCoding {

    var objects = [Object]()

    required init?(coder aDecoder: NSCoder) {

    }

    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(objects, forKey: "Objects") //// ERROR HERE
    }

}

Object 协议:

protocol Object: class, NSCoding {
    // Currently completely empty
}

StandardObject:

class StandardObject: NSObject, Object {

    required init?(coder aDecoder: NSCoder) {

    }

    func encodeWithCoder(aCoder: NSCoder) {

    }

}

我知道这与以下事实有关:您只能对对象(或它们的数组)进行编码,而不能对结构、枚举或协议进行编码。但是,Object 协议的声明是:

protocol Object: class, NSCoding

也就是说只有classes可以符合这个协议

这不应该意味着 objects 数组中只有 classes 的实例吗?为什么不能编码?

我也曾尝试在编码前将数组转换为 NSArray,但出现此错误:

cannot convert value of type '[Object]' to type 'NSArray' in coercion

所以这是我的两个问题:

  1. 如果我让 Object 协议只有符合它的对象,那么 Object 的数组不应该是对象的数组吗?
  2. 如果问题 1 由于某种原因无法解决,如何将 Object 的数组转换为能够使用 NSCoding 进行编码?

您需要将您的协议声明为 @objc,才能将其放入 Objective-C 世界:

@objc protocol Object: class, NSCoding {

然后编译器将知道他将能够 toll-free 将 Swift 数组与 NSArray 桥接,因为您将能够 build-up 数组只有从 NSObject.

派生的 类 的实例