Anyobject and Any in Swift

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 and AnyObject 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 ids 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 NSObjects.

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



Leave a reply



Submit