In Swift 3, everything is bridgeable to AnyObject
due to the introduction of _SwiftValue (see this Q&A for more info), that can wrap anything that isn't directly bridgeable to Objective-C in an opaque Objective-C compatible box.
Therefore is AnyObject
will always be true, as anything can be represented as an AnyObject
via wrapping in a _SwiftValue
.
One way to check whether a value is a reference type (as shown in this Q&A) is to type-check the type of the value against the metatype of AnyObject
, AnyClass
(aka AnyObject.Type
).
For generics, if you want to check whether the static type of T
is a reference type, you can do:
isObject = T.self is AnyClass
If you want to check whether the dynamic type of a value typed as T
is a reference type (such as val
in your example), you can use the type(of:)
function on the unwrapped value, as the aforementioned Q&A suggests:
if let val = val {
isObject = type(of: val) is AnyClass
// ...
}
The difference between these two approaches is that when T
is of type Any
(or a non AnyObject
abstract type), T.self is AnyClass
will return false
(which could be useful if you want a box where the value could be a reference or value type) – type(of: val) is AnyClass
however, will return whether val
itself is a reference type.