【问题标题】:Create instance from Class meta type in swift快速从类元类型创建实例
【发布时间】:2016-03-24 11:38:28
【问题描述】:

我有一个类包含其他类的类类型。而且这些类类型是在运行时注册的,所以实际上我不会在编译时知道类类型。但稍后我将使用这些注册的类类型来创建它们的实例。这是我的类定义

class registeredClassTypes
{
    var URLContext: AnyClass
    var ParserContext: AnyClass
    var ValidationContext: AnyClass

    func setTypes(URLContext: AnyClass, ParserContext: AnyClass, ValidationContext: AnyClass ) {
        self.URLContext=URLContext
        self.ParserContext = ParserContext
        self.ValidationContext = ValidationContext
    }
}

现在,我已经收集了包含这些类型的此类对象。

let classTypesObj = registeredClassTypes()
classTypesObj.setTypes(SomeClass.self, ParserContext: AnotherClass.self, ValidationContext: OneMoreClass.self)

有时我会需要这些类型的实例。虽然可以像下面这样但是使用类型转换来分类:

let requestType:SomeClass.Type = classTypesObj.URLContext as! SomeClass.Type
let obj = requestType.init()  //successfully creates the object of 'SomeClass'

我参考了一些博客,并了解到元类型的对象在没有类型转换的情况下无法创建。

但我的问题是我不会知道类“SomeClass”,所以我不能将它类型转换为“SomeClass”。 有没有办法实现这一点来动态解析类类型。我想要这样或任何其他方式:

let requestType = classTypesObj.URLContext 
let obj = requestType.init()

也提到了this blogthis blog,但他们也在进行类型转换。任何其他方式来解决这个问题也是可以接受的

【问题讨论】:

    标签: ios swift dynamic instantiation


    【解决方案1】:

    这种活力是 Objective C 的标志,更不用说在 Swift 中了。 Swift 更喜欢静态类型,所有的属性和方法都应该在编译时就知道。如果你想保持目前的做法,你可以在 ObjectiveC 中编写动态部分,然后在 Swift 中根据需要进行扩展。

    如果您想在纯 Swift 中执行此操作,请考虑协议:

    protocol URLContextProtocol {
        init()
        func method1 ()
        func method2 ()
    }
    
    protocol ParserContextProtocol {
        init()
        func method3 ()
        func method4 ()
    }
    
    protocol ValidationContextProtocol {
        init()
        func method5 ()
        func method6 ()
    }
    
    func setTypes(URLContext: URLContextProtocol, ParserContext: ParserContextProtocol, ValidationContext: ValidationContextProtocol) {
        // ...
    }
    

    用法:

    class URLContext1: URLContextProtocol { ... }
    class URLContext2: URLContextProtocol { ... }
    
    let classTypesObj = RegisteredClassTypes()
    classTypesObj.setTypes(URLContext: URLContext1, ...)
    
    // Init an instance
    let obj = classTypeObj.URLContext()
    

    【讨论】:

    • 感谢您的回复。如果我有许多符合每个协议的类,这个实现将如何工作,例如,我可能有 4-5 个类确认 URLContextProtocol 服务于不同的目的。当您只是将协议传递给 setTypes 方法时,我将如何知道要调用哪个类实例?
    • 你在协议而不是类上调用init。协议是您的类将实现某些属性和方法的承诺。它不限制这些属性或方法的实现方式。查看我编辑的答案
    猜你喜欢
    • 1970-01-01
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多