2016-04-25 96 views
4

我想檢查對象是給定類型的,我得到一個錯誤:檢查對象類型的失敗,「是不是一個類型的」錯誤

'expectedClass' is not a type

xcode

我的代碼如下。

func testInputValue(inputValue: AnyObject, isKindOfClass expectedClass: AnyClass) throws { 
    guard let object = inputValue as? expectedClass else { 
     // Throw an error 
     let userInfo = [NSLocalizedDescriptionKey: "Expected an inputValue of type \(expectedClass), but got a \(inputValue.dynamicType)"] 
     throw NSError(domain: RKValueTransformersErrorDomain, code: Int(RKValueTransformationError.UntransformableInputValue.rawValue), userInfo: userInfo) 
    } 
} 

我想弄清楚這裏可能會出現什麼問題。

+0

不能存儲'Type'的變量,並用它來'TypeCasting',它需要的類,所以你需要用實際的類來代替'expectedClass'說'String' ,'NSObject'等。 – CodetrixStudio

+0

相關:[在Swift中轉換爲元類型類型](http://stackoverflow.com/q/27882049) –

回答

3

你應該能夠使用泛型做到這一點:

func testInputValue<T>(inputValue: AnyObject, isKindOfClass expectedClass: T.Type) throws { 
    guard let object = inputValue as? T else { 
     ... 
    } 
} 
+0

我認爲這是正確的做法,但不應該'inputValue'被鍵入爲「T」而不是「AnyObject」? –

+1

@JoshCaswell'inputValue'是'T'的問題是你會得到這樣的警告:「從'T'到'T'的條件轉換總是成功(我想) – JAL

+0

你將無法調用方法的方式,如果'inputValue'類型爲'T',會導致錯誤,這會使得它變得沒有意義。 – dan

1

不是最偉大的答案永遠,但inputValue.dynamicType作品比較:

if inputValue.dynamicType == expectedClass { 
    print("inputValue.dynamicType \(inputValue.dynamicType) equals expectedClass \(expectedClass)") 
    // ... 
} 
3

你不應該做的類比較有==的建議在其他答案之一中,除非你特別想測試被測對象的類型是否應該與期望的類完全匹配,並且不允許它是被測類的子類。

您可以使用實例方法isKindOfClass來完成此操作,將子類考慮在內。請參閱下面的代碼示例。

注意:你可能會驚訝,這個工作在一個純粹的雨燕類類型,給出一個實例方法具有相同名稱的NSObject/NSObjectProtocol存在。它確實在純Swift中工作(如下面的示例代碼所示 - 使用Xcode 7.3,Swift 2.2.1進行測試),但不涉及@objc類型,只要您導入Foundation。我假定基於此,此實例方法作爲Foundation中的擴展方法添加到所有類類型中。

import Foundation 

class A { } 
class B { } 
class C: B { } 

enum ValueTestError: ErrorType { 
    case UnexpectedClass(AnyClass) 
} 

func testInputValue(inputObj:AnyObject, isKindOfClass expectedClass:AnyClass) throws { 
    guard inputObj.isKindOfClass(expectedClass) else { 
     throw ValueTestError.UnexpectedClass(inputObj.dynamicType) 
    } 
} 

let a = A() 
let b = B() 
let c = C() 

do { 
    try testInputValue(c, isKindOfClass: B.self) 
} catch { 
    print("This does not get printed as c is of type B (C is subclass of B).") 
} 

do { 
    try testInputValue(a, isKindOfClass: B.self) 
} catch { 
    print("This gets printed as a is not of type B.") 
} 

而且,重要的雖然isKindOfClass可作爲AnyObject實例方法,試圖把它叫做一個任意斯威夫特類類型的對象將只如果你的工作,反對AnyObject(第一投將永遠當然成功)。舉例說明這一點的代碼如下所示,並且在這個問題上還有更多over here

import Foundation 

class A {} 
let a = A() 

// the following compiles and returns 'true' 
(a as AnyObject).isKindOfClass(A.self) 

// the following fails to compile with "Value of type 'A' has no member 'isKindOfClass'" 
a.isKindOfClass(A.self) 
+0

除非我錯過了一些東西,你只能在NSObject(或符合'NSObjectProtocol'的對象)上使用'isKindOfClass',而不是Swift類。 – JAL

+0

這就是我的想法,因此也解決了這個問題。關心我的答案,它確實有效 - 在我的例子中只涉及純Swift類型,編譯並運行良好。 – mz2

+0

'這個方法作爲基礎擴展添加到所有類類型的對象作爲一個實例方法'你能告訴我擴展名存在於stdlib中嗎? – JAL

相關問題