Swift 3 - 如何验证对象的类类型

时间:2016-11-02 19:36:35

标签: ios swift3 casting type-inference

这行代码用于使用Swift 2,但现在在Swift 3中不正确。

if gestureRecognizer.isMember(of: UITapGestureRecognizer) { }

我收到此错误:类型名称后的预期成员名称或构造函数调用。

使用isMember(of:)的正确方法是什么?

4 个答案:

答案 0 :(得分:112)

最有可能的是,您不仅要检查类型,还要转换为该类型。在这种情况下,请使用:

if let gestureRecognizer as? UITapGestureRecognizer { }
else { /* not a UITapGestureRecognizer */ }

Swift施放操作符

这些运算符仅在Swift中可用,但在处理Objective C类型时仍然有效。

  • as运算符

    •   

      as运算符在编译时知道强制转换总是成功时执行强制转换,例如向上转换或桥接。 Upcasting允许您使用表达式作为其类型的超类型的实例,而不使用中间变量。

    • 如果可能,这是最优选的运算符。它保证了成功,而不用担心打开一个可选的或冒着崩溃的风险。
  • as?运算符

    •   

      as?运算符执行表达式到指定类型的条件转换。 as?运算符返回指定类型的可选项。在运行时,如果转换成功,表达式的值将包装在一个可选项中并返回;否则,返回的值为nil。如果保证转换为指定的类型失败或保证成功,则会引发编译时错误。

    • 这是第二个最受欢迎的运算符。用它来安全地处理无法执行铸造操作的情况。

  • as!运算符

    •   

      as!运算符将表达式强制转换为指定类型。 as!运算符返回指定类型的值,而不是可选类型。如果强制转换失败,则会引发运行时错误。 x as! T的行为与(x as? T)!的行为相同。

    • 这是最不受欢迎的运算符。我强烈建议不要滥用它。尝试将表达式强制转换为不兼容的类型 会导致程序崩溃。

Swift类型检查

如果您只想检查表达式的类型,没有转换为该类型,那么您可以使用这些方法。它们仅在Swift中可用,但在处理Objective C类型时仍然有效。

  • is运算符

    • is运算符在运行时检查表达式是否可以强制转换为指定的类型。如果表达式可以转换为指定的类型,则返回true;否则,它返回false
    • 适用于任何Swift类型,包括Objective C类型。
    • Swift相当于isKind(of:)
  • 使用type(of:)

    • is运算符不同,这可用于检查确切类型,而无需考虑子类。
    • 可以像:type(of: instance) == DesiredType.self
    • 一样使用
    • Swift相当于isMember(of:)

用于检查类型的遗留(目标C)方法

这些是NSObjectProtocol上的所有方法。它们可以在Swift代码中使用,但它们仅适用于派生自NSObjectProtocol 的类(例如NSObject的子类)。我建议不要使用这些,但我在这里提到它们是为了完整性

  • isKind(of:)

    • 返回一个布尔值,指示接收者是给定类的实例还是从该类继承的任何类的实例
    • 在Swift中避免这种情况,改为使用is运算符。
  • isMember(of:)

    • 返回一个布尔值,指示接收者是否是给定类的实例
    • NSObjectProtocol上的方法,因此仅适用于派生自NSObjectProtocol的类(例如NSObject的子类)
    • 在Swift中避免使用此功能,请改用type(of: instance) == DesiredType.self
  • conforms(to:)

    • 返回一个布尔值,指示接收器是否符合给定协议。
    • NSObjectProtocol上的方法,因此仅适用于派生自NSObjectProtocol的类(例如NSObject的子类)
    • 在Swift中避免这种情况,改为使用is运算符。

答案 1 :(得分:19)

有几种方法可以检查对象的类。大多数情况下,您需要使用isas?运算符,如下所示:

let gestureRecognizer: UIGestureRecognizer = UITapGestureRecognizer()

// Using the is operator
if gestureRecognizer is UITapGestureRecognizer {
    // You know that the object is an instance of UITapGestureRecognizer,
    // but the compiler will not let you use UITapGestureRecognizer specific
    // methods or properties on gestureRecognizer because the type of the
    // variable is still UIGestureRecognizer
    print("Here")
}

// Using the as? operator and optional binding
if let tapGestureRecognizer = gestureRecognizer as? UITapGestureRecognizer {
    // tapGestureRecognizer is the same object as gestureRecognizer and is
    // of type UITapGestureRecognizer, you can use UITapGestureRecognizer
    // specific methods or properties.
    print("Here")
}

// Using the type(of:) global function
if type(of: gestureRecognizer) == UITapGestureRecognizer.self {
    // gestureRecognizer is an instance of UITapGestureRecognizer, but not any
    // of its subclasses (if gestureRecognizer was an instance of a subclass of
    // UITapGestureRecognizer, the body of this if would not execute).
    // This kind of check is rarely usefull, be sure this is really what you
    // want to do before you use it.
    print("Here")
}

// Using the isKind(of:) method
if gestureRecognizer.isKind(of: UITapGestureRecognizer.self) {
    // Like for the is operator, you know that the object is an instance of
    // UITapGestureRecognizer (or any subclass of UITapGestureRecognizer).
    // This is the Objective-C version of the is operator and will only work
    // on classes that inherit from NSObject, don't use it in Swift.
    print("Here")
}

// Using the isMember(of:) method
if gestureRecognizer.isMember(of: UITapGestureRecognizer.self) {
    // gestureRecognizer is an instance of UITapGestureRecognizer, but not
    // any of its subclasses.
    // This is the Objective-C version of type(of:) and will only work on
    // classes that inherit from NSObject, don't use it in Swift.
    print("Here")
}

答案 2 :(得分:5)

你现在必须使用.self来引用类类型。

let a = UITapGestureRecognizer()
print (a.isMember(of: UIGestureRecognizer.self))

还有:

print (a is UITapGestureRecognizer)

答案 3 :(得分:3)

斯威夫特3:

if gestureRecognizer is UITapGestureRecognizer {
            //It's a tap
}