如何检查"Any"类型的对象是实现某些协议的具体类的数组

Nik*_*pov 6 arrays generics swift

我遇到了一个问题.考虑我有一个协议和两个实现它的类:

protocol Initiatable{
    init()
}

class A: Initiatable{
    required init() {}
}

class B: Initiatable{
    required init() {}
}
Run Code Online (Sandbox Code Playgroud)

然后在某些时候我正在创建一个数组并将其传递给函数:

var array = [A]()

func update(object: Any){

}

update(object: array)
Run Code Online (Sandbox Code Playgroud)

从该函数update我想传递object给另一个函数,如果它符合另一个函数的条件:

func process<T: Initiatable>(array: T){
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

那么如何检查类型对象Any是否为具体类实现Initiatable协议的数组?我想写点类似的东西

func update(object: Any){
    if let array = object as Array<T: Initiatable>{
        process(array: array)
    }
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用.代码如:

func update(object: Any){
    if let array = object as [Initiatable]{
        process(array: array)
    }
}

func process(array: [Initiatable]){ }
Run Code Online (Sandbox Code Playgroud)

编译很好,但这不是我想要的 - process函数应该接收一个具体实现的数组,Initiatable所以在某些时候它可以使用:

func process<T: Initiatable>(array: [T]){
    /* other code */
    T.init()
}
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?非常感谢你提前!

Nik*_*pov 0

我找到了解决此问题的解决方法:

func classTypeFrom(_ className: String) -> AnyClass!{
    if  let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String {
        let classStringName = "_TtC\(appName.characters.count)\(appName)\(className.characters.count)\(className)"
        return NSClassFromString(classStringName)
    }
    return nil;
}

func update(object: Any){
    if let array = object as? [Initiatable]{
        let arrayTypeName = "\(type(of: ar))"
        let objectTypeName = arrayTypeName.substringFrom(index: 6, length: arrayTypeName.characters.count - 7)
        if let arrayType = classTypeFrom(objectTypeName) as? Initiatable.Type{
            process(array: array, type: arrayType)
        }
    }
}

func process(array: [Initiatable], type: Initiatable.Type){
    var ar = array
    let newObj = type.init()
    ar.append(newObj)
}
Run Code Online (Sandbox Code Playgroud)