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

Dal*_*kar 3 swift swift3

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

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
Run Code Online (Sandbox Code Playgroud)

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

Ham*_*ish 8

在Swift 3中,AnyObject由于引入_SwiftValue(请参阅此问答以获取更多信息),所有内容都可以桥接,可以在不透明的Objective-C兼容框中包装任何不能直接桥接到Objective-C的内容.

因此is AnyObject总是如此,因为任何东西都可以表示为一个AnyObject包裹在一个_SwiftValue.

检查值是否为一个引用类型(如图单程这个问答)是键入检查的值的类型对的元类型AnyObject,AnyClass(又名AnyObject.Type).

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

isObject = T.self is AnyClass
Run Code Online (Sandbox Code Playgroud)

如果要检查键入的值的动态类型是否为T引用类型(例如val在您的示例中),则可以type(of:)在展开的值上使用该函数,如前面提到的问答所示:

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

    // ...
}
Run Code Online (Sandbox Code Playgroud)

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