如何测试泛型变量是否为AnyObject类型

时间:2016-09-17 11:59:30

标签: swift swift3

在Swift 3中,我无法再检查泛型变量类型是否为class(AnyObject)。以下代码返回true isObject,即使特定类型T和传递的值是struct而不是class。在Swift 2.3和2.2中,它按预期工作,isObjectfalse

struct Foo<T>
{
    var value: Any?
    var isObject: Bool = false

    init (val: T?)
    {
        if val != nil
        {
            // following line shows warnings in Swift 3
            // conditional cast from 'T?' to 'AnyObject' always succeeds
            // 'is' cast is always true
            isObject = val is AnyObject

            self.value = val
        }
    }
}

struct Bar
{
    var bar = 0
}

let b = Foo<Bar>(val: Bar())

print(b.isObject) // -> true

如何在Swift 3中使其正常工作?

1 个答案:

答案 0 :(得分:8)

在Swift 3中,由于引入了_SwiftValue(有关详细信息,请参阅this Q&A),所有内容都可以与AnyObject桥接,可以包装任何不能直接桥接的内容在不透明的Objective-C兼容盒中使用Objective-C。

因此,is AnyObject始终为真,因为任何内容都可以通过AnyObject包裹来表示为_SwiftValue

检查值是否为引用类型(如this Q&A所示)的一种方法是根据AnyObjectAnyClass的元类型键入 - 检查值的类型(又名AnyObject.Type)。

对于泛型,如果要检查T的静态类型是否为引用类型,则可以执行以下操作:

isObject = T.self is AnyClass

如果要检查键入为T的值的动态类型是否为引用类型(例如示例中为val),则可以使用type(of:)对展开的值起作用,正如前面提到的Q&amp; A所暗示的那样:

if let val = val {
    isObject = type(of: val) is AnyClass

    // ...
}

这两种方法之间的区别在于,当T属于Any类型(或非AnyObject抽象类型)时,T.self is AnyClass将返回false (如果你想要一个值可以是引用或值类型的框,这可能很有用) - type(of: val) is AnyClass但是,将返回val本身是否为引用类型。