AnyObject and Any in Swift
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
.
What is the difference between [String: AnyObject] and [String: Any]?
Any allowed use to work with a mix of different types including
function and non-class types
such as Int, String, and Bool. According to the documentation,
the elements in this array are Structs that are value types, so in theory
AnyObject shouldn’t work in these cases.
we would use AnyObject for Class types because they are a little more specific than Any. But again, the use of AnyObject is just an option.
more explaination you can find here.
I hope all your doubts will clear after go through this link
https://medium.com/@mimicatcodes/any-vs-anyobject-in-swift-3-b1a8d3a02e00
When is a variable a AnyObject but not a NSObject
On platforms with Objective-C compatibility (which means all of Apple's platforms and no others), every class type is (secretly) a subclass of the SwiftObject
class, which provides NSObject
protocol conformance.
On other platforms, NSObject
is “just another class”, implemented in Swift, so only a class that explicitly has NSObject
as a superclass has instances that are NSObject
s.
Why casting function type as AnyObject works
Behind the scenes as AnyObject
converts the casted value to an Objective-C compatible one: Int
's become NSNumber
, array's become NSArray
, and so on. Swift-only values get wrapped within opaque SwiftValue
instances.
print(type(of: test2)) // __SwiftValue
This is why adding as AnyObject
makes your code compile, as the right-hand of the operator is now an object.
AnyObject and generics in Swift
Yes. Though the syntax is the same (a colon), protocol inheritance is not the same thing as protocol conformance. Protocols do not conform to protocols; only types can conform to protocols. (AnyObject
is not special in this regard; your question is good but the title isn't getting at the issue.)
In your example:
Your T
needs to conform to AnyObject
. SomeClassProtocol
does not conform to AnyObject
. But any types that conform to SomeClassProtocol
will conform to AnyObject
.
So you need to pick which of these you really want:
- 1.
let test = GenericClass( t: SomeClass() )
(test
is a GenericClass<SomeClass>
.)
2.
class Class {
weak var object: AnyObject?
init(object: AnyObject) {
self.object = object
}
}
Class( object: SomeClass() )
You do have the option of subclassing, if that would be useful.
class GenericClass<T: AnyObject>: Class {
var t: T? {
get { object as? T }
set { object = newValue }
}
}
Casting Any to AnyObject in Swift
No downcasting from Any
to AnyObject
is not possible, and yes, the problem you have is about Any
not convertible to AnyObject
.
Any
can represent any type (classes, structs, enums, ints, strings etc.), whereas AnyObject
can represent reference types only (i.e. classes).
To solve the problem, I think you should change your dictionary to store values of AnyObject
type:
let dict:<String, AnyObject> = ["obj": self]
Note that even if the dictionary contains AnyObject
values, it can also store:
- numbers
- strings
- arrays
- dictionaries
because these types are automatically bridged to the corresponding objc types (NSNumber
, NSArray
, NSDictionary
, etc.)
If you really need to have max flexibility, then I suggest using NSDictionary
- but in that case value types must be explicitly boxed in reference types (i.e. int
in NSNumber
, etc.).
Also @rintaro's answer in another good option.
AnyObject vs. Struct (Any)
@nkukushkin's answer is correct, however, if what you want is a function that behaves differently depending on whether it’s passed a CGRect
or a CGStruct
, you are better off with overloading:
func print(rect: CGRect) {
println(NSStringFromCGRect(rect))
}
func print(size: CGSize) {
println(NSStringFromCGSize(size))
}
In comparison, the Any
will be both inefficient (converting your structs to Any
and back, could have a big impact if you do this a lot in a tight loop), and non-typesafe (you can pass anything into that function, and it will only fail at runtime).
If your intention is to coerce both types into a common type and then do the same operation on it, you can create a 3rd overload that takes that type, and have the other two call it.
Related Topics
Selecting Global or Object Print Function
Difference Between Functions and Closures
Xcode 8/Swift 3: Simple Uipicker Code Not Working
Separating Multiple If Conditions With Commas in Swift
How to Avoid Force Unwrapping a Variable
How to Create Instances of Managed Object Subclasses in a Nsmanagedobject Swift Extension
Uitableview With More Than One Custom Cells With Swift
How Does String.Index Work in Swift
What Is the In-Practice Difference Between Generic and Protocol-Typed Function Parameters
Cfrunloop in Swift Command Line Program
Why Optional Constant Does Not Automatically Have a Default Value of Nil
Why Can't I Instantiate an Empty Array of a Nested Class
How to Convert Unix Epoch Time to Date and Time in iOS Swift
Express For Loops in Swift With Dynamic Range
Swift Closure Async Order of Execution
Why Constant Constraints the Property from a Structure Instance But Not the Class Instance