如何从运行时创建的字符串中实例化Swift对象?

Sam*_*Sam 0 cocoa objective-c swift

在objectiveC库中有许多基于其类的名称(字符串表示)实例化对象的情况.

我已经与以下工作代码非常接近:

class Person{
    var age:Int = 1

    //somehow this is critical
    required init () {
    }
}

class Dog{
    var color:String = "Blue"

    //somehow this is critical
    required init () {
    }
}

/*
The basics
*/

let X = Person.self
var p1 = X()
p1.age = 5
println(p1.age)


/*
Instantiate from a String
*/
var hash1 = ["person":Person.self]

if let t = hash1["person"]{
    let p2 = t()
    p2.age = 8
    println(p2.age)
}
Run Code Online (Sandbox Code Playgroud)

最后一个字典片段接近真实世界的实现应该是什么样子,除了我们需要能够将多个Type放入字典中; 辨别两者并从结果中实例化.类似于以下非工作代码:

var hash2 = ["dog":Dog.self, "person":Person.self] // needed for real-world usage
if let t2 = hash2["person"]{ // warning
    let p3 = t2()   //error
    p3.age = 11
    println(p3.age)
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*min 5

看,Swift是非常类型安全的语言.所以当你弄乱任何不同的类型时,最好对编译器说什么我们会搞乱.所以hash2行看起来像这样:

var hash2: [String: Any] = ["dog": Dog.self, "person": Person.self]'
Run Code Online (Sandbox Code Playgroud)

这里你要说的是,该字典将使用键类型的字符串和值为Any类型(AnyObject来自Obj-c中的NSObject,这里是任何类型,因为Dog.self和Person.self不是来自obj-c和不一样的)

然后,在展开时,你需要说明它将是什么类型,所以下一个代码将是这样的:

if let t2 = hash2["person"] as? Person.Type {
    let p3 = t2() 
    p3.age = 11
    println(p3.age)
}
Run Code Online (Sandbox Code Playgroud)

在这里,我只是尝试不仅从字典中获取密钥,而且将其转换为Person.Type类型.Any当字典减速时,我提到的值可以是类型,我需要将其转换为特定类型才能使用age属性和()操作


UPD:

Swift是类型安全的,所以myObj.age如果myObj不是来自NSObject且没有特定类型,你就无法做到.在你的例子中,Dog和Person没有任何相似之处,因此将它们组合在一起是不合逻辑的.如果它有相似之处,那么你可以创建协议并投射到它.示例如下:

protocol Aged {
    var age: Int {get set}
    init()
}

class Person: Aged {
    var age: Int = 1

    //somehow this is critical
    required init () {
    }
}

class Dog: Aged {
    var age: Int =  5
    var color:String = "Blue"

    //somehow this is critical
    required init () {
    }
}

var hash2: [String: Any] = ["dog":Dog.self, "person":Person.self] // needed for real-world usage
if let t2 = hash2["person"] as? Aged.Type { 
    let p3 = t2() 
    println(p3.age)
}
Run Code Online (Sandbox Code Playgroud)