2016-08-24 78 views
4

我有一个各种类型的对象和一个数组类型的对象。对于每个对象,我想迭代类型数组并查看对象是否是该类型。类似这样的:检查一个对象是否是Swift中的类元类型的一个实例

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

比较https://stackoverflow.com/ q/44874126/2976878 – Hamish

+0

@Hamish:你的回答非常好!如果您在此提交答案,我很乐意接受。 –

+0

很高兴你发现它很有用!在这种情况下,可能会接近作为复制 – Hamish

回答

-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)") 
    } 
} 
+1

我真的很欣赏这种回应,但不幸的是,这并没有达到我想要的效果。首先,使用字符串需要很多额外的开销来维护,并且容易出错。该语言已经通过''dynamicType'''处理了所有这些(参见上面的示例)。其次,你的例子并不处理子/超类的情况:'''ChildB.title'''没有证据表明它是一个'''ChildB''和*'''Parent'' '。 –

相关问题