简体   繁体   English

Swift 3 - 类名/类型查找

[英]Swift 3 - class name/type lookup

My app uses hundreds of subclasses of a drawing class.我的应用程序使用绘图类的数百个子类。 (These subclasses are automatically generated from art files.) (这些子类是从艺术文件自动生成的。)

Ideally, I'd like to load in the names of some subclasses, check if those subclasses are actually available, and if so, instantiate them.理想情况下,我想加载一些子类的名称,检查这些子类是否实际可用,如果是,则实例化它们。

However, it would seem that the lack of NSClassFromString -style functionality in pure Swift means that I am forced to declare all my class names to the compiler in advance.然而,纯 Swift 中缺少NSClassFromString风格的功能似乎意味着我不得不提前向编译器声明我所有的类名。

eg getting a class via a very long, tedious switch statement:例如,通过一个非常冗长乏味的 switch 语句获取一个类:

func drawingObjectFromClassName(_ className: String) -> SomeDrawingProtocol?
{
    switch className {
        case "foo": return foo()
        case "bar": return bar()
        // etc.

        default:
            print("Warning: no class found for className: ", className)
            return nil
    }
}

But I'd also like to check for the existence of a subclass (eg "foo") without having to instantiate the object.但我还想检查子类(例如“foo”)是否存在,而不必实例化对象。

I could duplicate that switch statement to do this, but then I'd have two identical sets of keys to maintain.可以复制那个 switch 语句来做到这一点,但是我有两组相同的键要维护。 Yuck.哎呀。

So, one possible solution is to use a lookup table.因此,一种可能的解决方案是使用查找表。

Question : if I hard-code a Dictionary with all my subclass names as the keys, what syntax do I need for the values , such that a retrieved value can be instantiated as an object of the required class?问题:如果我用我的所有子类名称作为键对字典进行硬编码,那么需要什么语法,以便检索到的值可以实例化为所需类的对象? Thanks for any help.谢谢你的帮助。

protocol P {
    init()
}

extension String : P { }

extension Int : P { }

let types : [String : P.Type] = [
    "str": String.self,
    "int": Int.self
]

if let type = types["int"] {
    let object = type.init()
    assert(object is Int)
}

You can now use all the standard dictionary operations to check if things are present, cast the types you pull out however you want, etc.您现在可以使用所有标准字典操作来检查内容是否存在,根据需要转换您提取的类型等。

I defined the protocol in the example above in order to have a common initialiser (which is probably what you'll need in most cases), but you can simply use Any.Type and cast the type using as Int.Type if needed.我在上面的例子中定义了协议,以便有一个通用的初始化器(这可能是你在大多数情况下需要的),但你可以简单地使用Any.Type并在需要时使用as Int.Typeas Int.Type类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM