在Swift中调用只具有类名的初始化程序

AJ_*_*310 3 initializer ios swift

我想知道是否有办法只通过在Swift中拥有类名来调用初始化程序.

class Shape {
  let name: String
  var numberOfSides: Int?

  init(name: String) {
    self.name = name
  }
}
Run Code Online (Sandbox Code Playgroud)

伪代码:

let shapeClass = stringToClass("Shape")

let shape: Shape = shapeClass(name: "Something")
Run Code Online (Sandbox Code Playgroud)

new*_*cct 6

您不仅要尝试调用类函数,还要尝试动态调用初始化程序.为了能够在运行时获得的类上动态调用初始化程序,该类值的编译时类型必须是具有该初始化程序的类的元类型; 但由于初始化程序并不总是在Swift中继承,因此必须声明该初始化程序required.

这里我们用来NSClassFromString从字符串中获取一个类.(我@objc使用显式名称声明类,因为否则Swift类名称会从Objective-C的角度受到破坏,处理它会很麻烦.)但是,它返回AnyClass(ie AnyObject.Type),这是一个元类型,价值观是任何阶级.我们希望将它限制为继承的类Shape,因此我们可以使用Shape初始化程序,因此我们将其转换为Shape.Type(其值为下降的类的元类型Shape,包括在内).

我还通过简单地更改名称来证明它是多态的,因为它与子类的名称一起使用.

import Foundation
@objc(Shape)
class Shape {
  let name: String
  var type: String

  required init(name: String) {
    self.name = name
    self.type = "Shape"
  }
}
@objc(SubShape)
class SubShape : Shape {
  required init(name: String) {
    super.init(name: name)
    self.type = "SubShape"
  }
}
let shapeClass = NSClassFromString("SubShape") as Shape.Type
let shape: Shape = shapeClass(name: "Something")
println(shape.type) // prints "SubShape"
Run Code Online (Sandbox Code Playgroud)