检查对象是否是Swift中类meta类型的实例

时间:2016-08-24 04:46:27

标签: swift class reflection swift2 instance

我有各种类型的对象数组和类型数组。对于每个对象,我想迭代类型数组并查看对象是否是该类型。像这样:

class Parent {}
class ChildA: Parent {}
class ChildB: Parent {}
class GrandChildA: ChildA {}

var objects: [Any] = ["foo", ChildA(), ChildA(), ChildB(), GrandChildA()]
var classes = [Parent, ChildA, ChildB] // This line doesn't compile!!

for obj in objects {
    for cls in classes {
        if obj is cls {
            NSLog("obj matches type!")
        }
    }
}

这不起作用,因为您无法在数组中存储类。据我了解,您可以存储类类型,例如ChildA.self

ChildA().dynamicType == ChildA.self // true

但是这并没有处理子类:

ChildA().dynamicType == Parent.self // false

显然is运算符解决了子类的情况:

ChildA() is Parent // true

但如果我想使用is,我就不知道如何将类类型存储在数组中。

我能以某种方式使用Swift和一些反射巫术来完成我想要的东西吗?

如果标题有误导性,我很抱歉 - 我不太了解这一点,以形成一个正确的问题。

1 个答案:

答案 0 :(得分:-2)

通过为每个班级添加标题,您可以打开它们。另外,您是否考虑过使用协议而不是超类?

也许是这样的:

protocol Parentable {
    var title : String { get set }
}

class ChildA : Parentable{
    var title: String
    init() {
        self.title = "ChildA"
    }
    init(title: String){
       self.title = title
    }
}
class ChildB: Parentable {
    var title: String
    init(){
        self.title = "ChildB"
    }
}
class GrandChildA: ChildA {
    override init() {
        super.init(title: "GrandChild")
    }
}

var objects: [Parentable] = [ChildA(), ChildA(), ChildB(), GrandChildA()]

for obj in objects {
    switch obj.title {
    case "ChildA":
        print("Object is of type \(obj.title)")
    case "ChildB":
        print("Object is of type \(obj.title)")
    case "GrandChild":
        print("Object is of type \(obj.title)")
    default :
        print("Object is of type \(obj.title)")
    }
}

如果你需要通过引用传递的对象,你也可以使用像这样的超类:

class Parent {
    var title: String

    init() {
        self.title = "Parent"
    }
    init(title: String) {
        self.title = title
    }
}
class ChildA: Parent {
    override init() {
        super.init(title: "ChildA")
    }
    override init(title: String) {
        super.init(title: title)
    }
}
class ChildB: Parent {
    override init() {
        super.init(title: "ChildB")
    }
}
class GrandChildA: ChildA {
    override init() {
        super.init(title: "GrandChild")
    }
}

    var objects: [Parent] = [ChildA(), ChildA(), ChildB(), GrandChildA()]

    for obj in objects {
        switch obj.title {
        case "ChildA":
            print("Object is of type \(obj.title)")
        case "ChildB":
            print("Object is of type \(obj.title)")
        case "GrandChild":
            print("Object is of type \(obj.title)")
        default :
            print("Object is of type \(obj.title)")
    }
}