【发布时间】:2016-04-15 17:59:20
【问题描述】:
我需要从脚本中读取的字符串名称创建对象。我不想使用 Objective-C 运行时。
在我的 C++ 实现中,每个类都通过全局静态变量向对象工厂单例注册自己。当 dll 加载时,全局变量被初始化,所有可用的类都被注册。
我不希望对象工厂具有所有可能类型的硬编码预知识。
在 Swift 中,所有全局变量都是延迟初始化的,因此我的 C++ 注册策略不起作用。
是否有一些初始化 API 可以在每个模块加载时快速调用一次? 如果没有,有没有人知道课程注册的好主意?
public enum DynamicTypeFactoryError : ErrorType {
case ClassNotRegistered
}
public protocol DynamicType {
static var dynamicClassName: String { get }
init()
}
public struct DynamicTypeRegistraion<T: DynamicType> {
public init() {
DynamicTypeFactory.inst.register(T.dynamicClassName, factory: { T() })
}
}
//===========================================================================
// singleton
public class DynamicTypeFactory {
// properties
public static let inst = DynamicTypeFactory()
typealias ClassFactoryType = (Void) -> DynamicType
var registry = [String : ClassFactoryType]()
// methods
public func create(className: String) throws -> DynamicType {
// make sure the class exists
guard let factory = registry[className] else {
throw DynamicTypeFactoryError.ClassNotRegistered
}
return factory()
}
/// This is used to register an object so it can be dynamically created
/// from a string.
public func register(className: String, factory: (Void) -> DynamicType) {
if (registry[className]) != nil {
// TODO - this should be logged
assertionFailure("Class: \(className) is already registered")
} else {
registry[className] = factory
}
}
}
//===========================================================================
// MyObject
public struct MyObject : DynamicType {
// properties
static let registration = DynamicTypeRegistraion<MyObject>()
public static var dynamicClassName = "MyObject"
public init() {
}
}
// Usage
let myObj = try? DynamicTypeFactory.inst.create("MyObject")
由于MyObject的静态注册没有初始化,调用create失败,因为它还没有注册。
【问题讨论】:
-
Swift 中没有(据我所知)这样的机制。例如,参见stackoverflow.com/questions/28422468/… 或stackoverflow.com/questions/24898453/… 中的讨论。
-
您能否举例说明您正在做什么以及为什么延迟初始化不适用于您的情况?也许有一个变通办法,通过一个例子就会变得很明显。
标签: swift module initialization