替代Swift中的load方法

Tro*_*mas 6 objective-c swift

我正在开发Swift中的应用程序.我想为应用程序设计一个允许对象之间松散耦合的系统,而一个策略(我在其他语言中成功使用)就是创建一个我称之为实例工厂的东西.这很简单,这是我在Swift中提出的基本实现:

import Foundation

private var typeGenerators = Dictionary<String, InstanceFactory.GeneratorCallback>()

public class InstanceFactory: NSObject {
    public typealias GeneratorCallback = () -> AnyObject!

    public class func registerGeneratorFor(typeName: String, callback: GeneratorCallback) {
        typeGenerators[typeName] = callback
    }

    public class func instanceOf(typeName: String) -> AnyObject! {
        return typeGenerators[typeName]?()
    }
}
Run Code Online (Sandbox Code Playgroud)

这个想法是,当一个对象实例需要访问另一个对象实例时,而不是直接创建那个将两个对象紧密耦合的实例,第一个对象将通过调用instanceOf方法推迟工厂提供所需的实例.工厂将知道如何提供各种实例类型,因为这些类型将向工厂注册并提供可生成实例的闭包.

诀窍是如何让类注册到工厂.我以前在Objective-C中创建了一个类似的工厂,我注册工作的方式是覆盖需要向工厂注册的每个类的+ load方法.这对Objective-C非常有用,我认为它也适用于Swift,因为我会限制工厂只提供从NSObject派生的对象.看起来我已经开始工作了,我花了大量精力设计课程以利用工厂.

但是,在升级到Xcode 6.3后,我发现Apple不允许在Swift中使用load类方法.没有这个,我不知道允许类自动向工厂注册的机制.

我想知道是否有其他方式让注册工作.

哪些替代方案可以允许类别在工厂注册,或者可以使用哪些其他技术来实现工厂提供的相同类型的松耦合?

Tom*_*aia 0

考虑采用使用协议的 Swift 方法。我认为该解决方案实际上比 Objective-C 方法更简单。自我约束有一些变化,如果您对类有更多的控制,那就更好了。

// define a protocol to create an instance of a class
protocol FactoryInstantiable {
    static func makeFactoryInstance() -> AnyObject
}

// Factory for generating new instances
public class InstanceFactory: NSObject {
    public class func instanceOf(typeName: String) -> AnyObject! {
        if let ProductType = NSClassFromString(typeName) as? FactoryInstantiable.Type {
            return ProductType.makeFactoryInstance()
        } else {
            return nil
        }
    }
}


// your class which generally could be defined somewhere else 
class MyClass {
    var counter : Int

    init(counter: Int) {
        self.counter = 0
    }
}

// extension of your class to conform to the FactoryInstantiable protocol
extension MyClass : FactoryInstantiable {
    static func makeFactoryInstance() -> AnyObject {
        return MyClass(counter: 0)
    }
}
Run Code Online (Sandbox Code Playgroud)