AnyObject and Any in Swift
I don't understand when to use AnyObject
and when to use Any
in Swift.
In my case, I've a Dictionary
[String: ???]
??? : Can be Int
, Double
, Float
, String
, Array
, Dictionary
Can someone explain me the difference between Any
and AnyObject
and which one to use in my case.
AnyObject
is only for reference types (classes), Any
is for both value and reference types.
So you should go for [String: Any]
.
Type Casting for Any and AnyObject
Swift provides two special types for working with nonspecific types:
Any
can represent an instance of any type at all, including function types.AnyObject
can represent an instance of any class type.NOTE:
Use
Any
andAnyObject
only when you explicitly need the behavior and capabilities they provide. It is always better to be specific about the types you expect to work with in your code.
From The Swift Programming Language: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TypeCasting.html#//apple_ref/doc/uid/TP40014097-CH22-ID342
-
Also note that when you work with Cocoa API, it's common to receive an Array of AnyObject, this is because Objective-C arrays are NOT typified. So you need to cast them to the array type you expect.
-
EDIT: (december 22, 2015)
On the last statement, note that this is changing with Swift 2.0 and Xcode 7.
Apple has introduced ‘Lightweight’ generics in Objective-C so lots of Cocoa APIs now already returns the correct type.
EDIT: (october 18, 2016)
Note that, as of Swift 3.0, Objective-C id
s are now imported as Any
, not anymore as AnyObject
.
Whether you use Any
or AnyObject
depends on your intended use:
If your dictionary will be used only within Swift code, then you should use Any
because your types (Int
, Double
, Float
, String
, Array
, and Dictionary
) are not objects.
If you will be passing your dictionary to Objective-C routines that expect an NSDictionary
, then you should use AnyObject
.
When you import Foundation
or import UIKit
or import Cocoa
, it is possible to declare your array as [String: AnyObject]
, but in this case Swift is treating your Int
, Double
, Float
literals as NSNumber
, your String
s as NSString
, your Array
s as NSArray
, and your dictionaries as NSDictionary
, all of which are objects. A dictionary using AnyObject
as the value type is convertible to NSDictionary
, but one using Any
is not.
According to Apple’s Swift documentation,
- Any can represent an instance of any type at all, including function types and optional types.
- AnyObject can represent an instance of any class type.
For more details please check this: Blog
Check this SO answer:
Generics are type safe, meaning if you pass a string as a generic and try to use as a integer the compiler will complain and you will not be able to compile your (which is good). (This happens because Swift is using Static typing, and is able to give you a compiler error). If you use AnyObject the compiler has no idea is this object can be treated as a String or as an Integer and basically will allow you to do whatever you want with it (which is bad) as if you try to use an object that has been passed as a String when it is an Integer the application will crash. (This happens because Swift is using Dynamic typing and will only give you a runtime error)