2016-08-24 80 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'' '。 –

相關問題