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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40388337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 10:42:24  来源:igfitidea点击:

Swift 3 - How to verify class type of object

iosswift3castingtype-inference

提问by Van Du Tran

This line of code used to work with Swift 2, but now is incorrect in Swift 3.

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

if gestureRecognizer.isMember(of: UITapGestureRecognizer) { }

I get this error: Expected member name or constructor call after type name.

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

What is the correct way to use isMember(of:)?

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

回答by Alexander - Reinstate Monica

Most likely, you'll want to not only check the type, but also cast to that type. In this case, use:

很可能,您不仅要检查类型,还要强制转换为该类型。在这种情况下,请使用:

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


Swift casting operators

Swift 转换运算符

These operators are only available in Swift, but still work when dealing with Objective C types.

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

  • The asoperator

    • The asoperator performs a cast when it is known at compile time that the cast always succeeds, such as upcasting or bridging. Upcasting lets you use an expression as an instance of its type's supertype, without using an intermediate variable.

    • This is the most preferable operator to use, when possible. It guarentees success, without worrying about unwrapping an optional or risking a crash.
  • The as?operator

    • The as?operator performs a conditional cast of the expression to the specified type. The as?operator returns an optional of the specified type. At runtime, if the cast succeeds, the value of expressionis wrapped in an optional and returned; otherwise, the value returned is nil. If casting to the specified typeis guaranteed to fail or is guaranteed to succeed, a compile-time error is raised.

    • This is the second most preferable operator to use. Use it to safely handle the case in which a casting operator can't be performed.

  • The as!operator

    • The as!operator performs a forced cast of the expression to the specified type. The as!operator returns a value of the specified type, not an optional type. If the cast fails, a runtime error is raised. The behavior of x as! Tis the same as the behavior of (x as? T)!.

    • This is the least preferable operator to use. I strongly advise against abusing it. Attempting to cast an expression to an incompatible type crashes your program.

  • as运营商

    • as操作者执行时,它在编译时,该铸造总是成功,如向上转型或桥接已知的铸造。Upcasting 允许您将表达式用作其类型超类型的实例,而无需使用中间变量。

    • 如果可能,这是最可取的操作符。它保证成功,而无需担心打开可选组件或冒崩溃的风险。
  • as?运营商

    • as?操作者进行表达的条件铸造为指定的类型。所述as?操作者返回一个可选的指定类型的。在运行时,如果转换成功,则表达式的值被包装在一个可选项中并返回;否则,返回的值为nil。如果强制转换为指定的类型一定会失败或一定会成功,则会引发编译时错误。

    • 这是第二个最适合使用的运算符。使用它可以安全地处理无法执行铸造操作员的情况。

  • as!运营商

    • as!操作者进行的表达的强制投为指定的类型。的as!操作者返回指定的值类型,而不是一个可选类型。如果转换失败,则会引发运行时错误。的行为x as! T与 的行为相同(x as? T)!

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



Swift type checking

Swift 类型检查

If you merely want to check the type of an expression, withoutcasting to that type, then you can use these approaches. They are only available in Swift, but still work when dealing with Objective C types.

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

  • The isoperator

    • The isoperator checks at runtime whether the expression can be cast to the specified type. It returns trueif the expression can be cast to the specified type; otherwise, it returns false
    • Works on any Swift type, including Objective C types.
    • Swift equivalent of isKind(of:)
  • Using type(of:)

    • Unlike the isoperator, this can be used to check the exact type, without consideration for subclasses.
    • Can be used like: type(of: instance) == DesiredType.self
    • Swift equivalent of isMember(of:)
  • is运营商

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

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


Legacy (Objective C) methods for checking types

用于检查类型的传统(Objective C)方法

These are all methods on NSObjectProtocol. They can be used in Swift code, but they only apply work with classes that derive from NSObjectProtocol(such as subclasses of NSObject). I advise against using these, but I mention them here for completeness

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

  • isKind(of:)

    • Returns a Boolean value that indicates whether the receiver is an instance of given class or an instance of any class that inherits from that class
    • Avoid this in Swift, use isoperator instead.
  • isMember(of:)

    • Returns a Boolean value that indicates whether the receiver is an instance of a given class
    • Avoid this in Swift, use type(of: instance) == DesiredType.selfinstead.
  • conforms(to:)

    • Returns a Boolean value that indicates whether the receiver conforms to a given protocol.
    • Avoid this in Swift, use isoperator instead.
  • isKind(of:)

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

    • 返回一个布尔值,指示接收者是否是给定类的实例
    • 在 Swift 中避免这种情况,type(of: instance) == DesiredType.self而是使用。
  • conforms(to:)

    • 返回一个布尔值,指示接收者是否符合给定的协议。
    • 在 Swift 中避免这种情况,请改用is运算符。

回答by deadbeef

There are several ways to check the class of an object. Most of the time you will want to use either the isor the as?operators like so:

有几种方法可以检查对象的类。大多数情况下,您会希望使用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")
}

回答by Josh Homann

You have to use .self to refer the class type now.

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

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

There is also:

还有:

print (a is UITapGestureRecognizer)

回答by Zigglzworth

Swift 3:

斯威夫特 3:

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