2016-09-17 72 views
3

在Swift 3中,我不再能够检查泛型变量类型是否为类(AnyObject)。以下代码返回trueisObject即使特定类型T和传递的值是结构,而不是类。在Swift 2.3和2.2中,它按预期工作,isObjectfalse如何测试泛型变量是否为AnyObject类型

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中正常工作?

+0

即使'90是AnyObject'返回'true'。听起来像是一个bug。 – MirekE

+1

相关:[AnyObject不工作在Xcode8 beta6?](http://stackoverflow.com/questions/39033194/anyobject-not-working-in-xcode8-beta6) – Hamish

回答

7

在斯威夫特3,一切都是桥接至AnyObject由于引进的_SwiftValue(见this Q&A获取更多信息),它可以包含任何不是直接桥接来的Objective-C在一个不透明的Objective-C的兼容框。

因此is AnyObject将始终为真,因为任何东西都可以通过包装在_SwiftValue中表示为AnyObject

一种方法来检查一个值是否是一个引用类型(如图this Q&A)是键入检查的值的类型针对AnyObjectAnyClass(又名AnyObject.Type)的元类型。

仿制药,如果你想查看静态类型的T是否是引用类型,你可以这样做:

isObject = T.self is AnyClass 

如果你想检查一个值的动态类型是否类型为T是引用类型(如在你的例子val)时,可以使用type(of:)功能上展开的值,作为所述的Q &甲表明:

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

    // ... 
} 

这两种方法之间的区别是,当TAny型(或非AnyObject抽象型),T.self is AnyClass将返回false(如果你想有一个对话框,在其中的价值可能是一个引用或值类型可能是有用的) - type(of: val) is AnyClass但是,将返回val本身是否是引用类型。