How to test whether generic variable is of type AnyObject
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.
Check if `Any` value is object
UPDATE
The code I have shown below is reported as not working in release build.
(Please see Paul Cantrell's comment below.)
Apologies for my "as far as I tested" was too limited.
I'll update this answer when I find some further info about this.
I'm not sure we can see this behaviour in the next beta (or GM or Released version...), but this works as you expect in Xcode 8 beta 6.
let foo: Any = 4
if type(of: foo) is AnyClass {
print("It's an object.")
let object = foo as AnyObject
//do something with `object` that requires reference semantics
} else {
print("It's not an object.") //->It's not an object.
}
class MyClass {}
let bar: Any = MyClass()
if type(of: bar) is AnyClass {
print("It's an object.") //->It's an object.
let object = foo as AnyObject
//do something with `object` that requires reference semantics
} else {
print("It's not an object.")
}
let baz: Any = Array<AnyObject>()
if type(of: baz) is AnyClass {
print("It's an object.")
let object = foo as AnyObject
//do something with `object` that requires reference semantics
} else {
print("It's not an object.") //->It's not an object.
}
I cannot check all possible cases, so there may be some edge cases where this does not work. But as far as I tested, this seems to work as expected.
Swift check type against a generic type
You cannot tell a function what the types of its generic placeholders are (unlike with a generic struct). It must infer them from the context e.g. its arguments.
One way to do what you want is to add another argument related to type T
. Rather than pass in a dummy value, you could use the metatype of the type you want:
func generic<T>(parameter: AnyObject, type: T.Type) -> Bool {
if parameter is T {
return true
} else {
return false
}
}
let o: AnyObject = "hello"
generic(o, String.self) // true
generic(o, NSString.self) // also true
generic(o, Int.self) // false
However, I would ask you, what is it you think you're achieving here? You've essentially done nothing more than implement is
as a function:
o is String // true
o is NSString // true
o is Int // false
The point of generics is to operate on arguments generically, but you aren't giving the function any argument of a specific type to actually do any work on (hence the inability to infer one).
Related Topics
What Does the '@' Symbol Mean in Swift
Value of Optional Type Cgfloat Not Unwrapped Error in Swift
"Generic Parameter Could Not Be Inferred" in Swiftui Uiviewrepresentable
Non-Strong References Not Working in Playground
Single-Element Parethesized Expressions/Tuples VS Common Use of Parentheses
Segue from a Slpagingviewswift Vc and Dismiss the Destination Vc to Return
How to Make Keyboard Dismiss When I Press Out of Searchbar on Swift
Pointers, Pointer Arithmetic, and Raw Data in Swift
How to Remove Spaces from a String in Swift
How to Implement Copy Constructor in Swift Subclass
Make Property of Type and Also Conform to Protocol in Swift
Swiftui Customized Text Field in Osx
Know When an Iteration Over Array with Async Method Is Finished
Expandable Sections Uitableview Indexpath Swift
What Is the Way to Save Fonts and Sizes in Firebase for Textview Swift
How to Assign an Optional Binding Parameter in Swiftui
Extend Existing Protocols to Implement Another Protocol with Default Implements