Swift AnyObject - 将协议数组向下转换为 [AnyObject]

Swift AnyObject - Down casting an array of protocols to [AnyObject]

如何将协议实例数组向下转换为 AnyObjects?我在下面的代码示例中尝试了一些更合理的想法。

protocol Nameable : class {
    var name: String { get }
}

class Person: Nameable {
    var name: String

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

class Example {

    func setArray(array: [AnyObject]?, forKey: String)
    {
        print("hello world")
    }
}

var personOne = Person(name: "Evan")
var personTwo = Person(name: "Brian")

var array: [ Nameable ] = [ personOne, personTwo ]

var anotherArray = array.map({ [=11=] as AnyObject })    // OMG gross!
var yetAnotherArray = array as [ AnyObject ]         // Nope.
var evenYetAnotherArray = array as? [ AnyObject ]    // Nope.
var omgThisIsAnArray = Array<AnyObject>(array)       // Ha ha, srsly. Nope.

var myExample = Example()
myExample.setArray(anotherArray, forKey: "Named")

就其价值而言,setArray(_ anArray: [AnyObject]?, forKey aKey: String) 方法签名来自 Apple 的 NSUbiquitousKeyValueStore class,因此我无法真正重新设计它以确保类型安全。

它并不完美,但如果协议和 class 都是 @objc(以及 class subclasses NSObject),它就可以工作:

@objc protocol Nameable: class {
    var name: String { get }
}

@objc class Person: NSObject, Nameable {
    var name: String
    init(name: String) {
        self.name = name
    }
}

...

var array: [Nameable] = [personOne, personTwo]
let array2 = array as [AnyObject] // ✓

这并没有真正直接回答您的问题,但我认为这不会像您期望的那样起作用。

来自 NSUbiquitousKeyValueStore setArray 的文档:

An array whose contents can be stored in a property list format. In other words, the objects in the array must be of the types NSNumber, NSString, NSDate, NSData, NSArray, or NSDictionary. The total size (in bytes) of the array and its contents must not exceed the per-key size limits.

您正试图将数据放入不是上述任何内容的数据中,我猜您会 运行 遇到问题。

像这样的东西会起作用:

import UIKit // For String<->NSString bridging

protocol Nameable : class  {
    var name: String { get }
}

class Person: Nameable {
    var name: String

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

class Example {

    func setArray(array: [AnyObject]?, forKey: String)
    {
        print("hello world")
    }
}

var personOne = Person(name: "Evan")
var personTwo = Person(name: "Brian")

var array: [ Nameable ] = [ personOne, personTwo ]

var nameArray = array.map({ [=10=].name }) // Now [String]

var myExample = Example()
myExample.setArray(nameArray, forKey: "Named")

或者您可以通过其他方式序列化您的 Swift 对象,以将它们放入受支持的 类 之一。