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

时间:2016-04-15 01:04:25

标签: swift protocols anyobject

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

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({ $0 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课程,因此我无法重新设计这种类型安全。

2 个答案:

答案 0 :(得分:4)

这不完美,但如果协议和类都是@objc(和类子类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] // ✓

答案 1 :(得分:0)

这并没有直接回答你的问题,但我认为这不会像你期望的那样有效。

来自NSUbiquitousKeyValueStore的文档setArray:

  

一个数组,其内容可以以属性列表格式存储。换句话说,数组中的对象必须是 NSNumber NSString NSDate NSData 类型, NSArray NSDictionary 。数组及其内容的总大小(以字节为单位)不得超过每个键的大小限制。

您尝试将数据放入上述任何内容并且我猜测您会遇到问题。

这样的事情会起作用:

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({ $0.name }) // Now [String]

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

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