模块加载时如何执行一次?

时间:2016-04-15 17:59:21

标签: swift module initialization

我需要从我从脚本中读取的字符串名称创建对象。我不想使用Objective-C运行时。

在我的C ++实现中,每个类通过全局静态变量向对象工厂单例注册自己。加载dll时,初始化全局变量,并注册所有可用的类。

我不希望对象工厂拥有所有可能类型的硬编码预先知识。

在Swift中,所有全局变量都被懒惰地初始化,所以我的C ++注册策略不起作用。

是否有一些init 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失败,因为它尚未注册。

2 个答案:

答案 0 :(得分:0)

在查看了Martin R发布的链接后,似乎没有静态的“非懒惰”初始化,这是设计的。因此,Swift应用程序需要采用不同的方法。谢谢马丁!

答案 1 :(得分:0)

Objective C中有两种方法用于加载和初始化类。 +加载和+初始化 1.在swift中你可以使用&#34; public override class func initialize()&#34;要记下你的初始化代码,请注意它会被懒惰地调用。

  1. 在Swift 1.2中删除了对覆盖负载的支持
  2. 以下是关于初始化方法

    的文档

    &#34;运行时将初始化发送到程序之前的程序中的每个类,或从程序中发送的第一条消息,从程序中发送任何继承自它的类。运行时以线程安全的方式将初始化消息发送到类。超类在其子类之前收到此消息。&#34;