2016-04-15 41 views
3

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

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)方法签名来自苹果的NSUbiquitousKeyValueStore类,所以我真的不能重新设计该是类型安全的。

+0

如果一个对象符合AnyObject类型,但其类型更加明确,则不需要将对象强制转换为AnyObject来匹配方法签名。在你的情况 - 正如埃里克在他的回答中提到的 - 问题是'NSUbiquitousKeyValueStore'只支持属性列表兼容类型。 – vadian

回答

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

谢谢!这里的关键是'AnyObject'注解了'@ objc',而我的协议是_not_。因此它是有道理的,它是不可能的。 – edelaney05

0

这并不能真正直接回答你的问题,但我认为这不会像你期望的那样。

从文档为NSUbiquitousKeyValueStore setArray:

一个数组,其内容可以被存储在属性列表格式。换句话说,阵列中的对象必须是类型的的NSNumber的NSString的NSDateNSData的的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") 

或者你可以你的序列化对象斯威夫特一些其他的方式,让他们为支持的类别之一。