Swift 3 – 如何validation对象的类types

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

if gestureRecognizer.isMember(of: UITapGestureRecognizer) { } 

我得到这个错误:预期的成员名称或types名称后的构造函数调用。

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

最有可能的是,你不仅要检查types,而且要转换为该types。 在这种情况下,使用:

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

Swift中的操作符

这些运算符只在Swift中可用,但在处理Objective Ctypes时仍然有效。

  • as运营商

    • as运算符在编译时知道转换总是成功,例如向上转换或桥接。 向上转换允许您使用expression式作为其types的超types的实例,而不使用中间variables。

    • 如果可能的话,这是最可取的操作符。 它保证成功,而不必担心打开选项或冒险。
  • as? 操作者

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

    • 这是使用的第二个最可取的操作符。 使用它来安全地处理铸造操作员不能执行的情况。

  • as! 操作者

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

    • 这是最不喜欢使用的运算符。 我强烈build议不要滥用。 尝试将expression式转换为不兼容的types会导致程序崩溃。


本机Swift技术来检查types

如果你只是想检查一个expression式的types, 而不是转换成这种types,那么你可以使用这些方法。 它们仅在Swift中可用,但在处理Objective Ctypes时仍然有效。

  • is运营商

    • is运算符在运行时检查expression式是否可以转换为指定的types。 如果expression式可以转换为指定的types,则返回true ; 否则,它返回false
    • 适用于任何Swifttypes,包括Objective Ctypes。
    • 等价的isKind(of:)
  • 使用type(of:)

    • is运算符不同,这可以用来检查确切的types,而不考虑子类。
    • 可用于: type(of: instance) == DesiredType.self
    • 相当于isMember(of:)

Objective C检查types的方法

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

  • isKind(of:)

    • 返回一个布尔值,指示接收方是给定类的实例还是从该类inheritance的任何类的实例
    • 避免在Swift中使用这个操作符。
  • isMember(of:)

    • 返回一个布尔值,指示接收者是否是给定类的实例
    • NSObjectProtocol上的方法,因此只对从NSObjectProtocol派生的类(如NSObject子类)
    • 避免在Swift中使用type(of: instance) == DesiredType.self来代替。
  • conforms(to:)

    • 返回一个布尔值,指示接收器是否符合给定的协议。
    • NSObjectProtocol上的方法,因此只对从NSObjectProtocol派生的类(如NSObject子类)
    • 避免在Swift中使用这个操作符。

有几种方法来检查对象的类。 大多数时候你会想要使用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") } 

你必须使用.self现在引用类的types。

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

还有:

 print (a is UITapGestureRecognizer) 

Swift 3:

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