This question was inspired by mz2's answer on the question Check for object type fails with "is not a type" error.
Consider an empty Swift class:
class MyClass { }
Attempting to call any NSObjectProtocol
methods on an instance of this class will result in a compile-time error:
let obj = MyClass()
obj.isKindOfClass(MyClass.self) // Error: Value of type 'MyClass' has no member 'isKindOfClass'
However, if I cast the instance as AnyObject
, my object now conforms to NSObjectProtocol
and I can call the instance methods defined by the protocol:
let obj: AnyObject = MyClass()
obj.isKindOfClass(MyClass.self) // true
obj.conformsToProtocol(NSObjectProtocol) // true
obj.isKindOfClass(NSObject.self) // false
My object doesn't inherit from NSObject
, but still conforms to NSObjectProtocol
. How does AnyObject
conform to NSObjectProtocol
?
It’s equivalent to ‘id’ in Objective-C. AnyObject can represent an instance of any class type. If you specifically define the array as [ AnyObject ], you are indicating to the compiler that you are aware that the elements are of the reference data type only.
This protocol is imported into Swift with the name NSObjectProtocol. An object that conforms to this protocol can be considered a first-class object. Such an object can be asked about its: Class, and the place of its class in the inheritance hierarchy. Conformance to protocols. Ability to respond to a particular message.
The Cocoa root class NSObject adopts this protocol, so all objects inheriting from NSObject have the features described by this protocol. var superclass: AnyClass? Returns the class object for the receiver’s superclass. Required. Returns a Boolean value that indicates whether the receiver and a given object are equal. Required.
In the Cocoa / Objective-C world, AnyObject is id
. Having cast this object to AnyObject, you can send any known Objective-C message to it, such as isKindOfClass
or conformsToProtocol
. Now, when you say isKindOfClass
or conformsToProtocol
, you're not in the Swift world any more; you're talking to Cocoa with Objective-C. So think about how Objective-C sees this object. All classes in the Objective-C world descend from some base class; a baseless class like MyClass is impossible. And every base class in the Objective-C world conforms to the NSObject protocol (which Swift calls NSObjectProtocol); that's what it is to be (or descend from) a base class! Therefore, to get it into the Objective-C world, Swift presents MyClass as descending from a special bridging base class SwiftObject which does indeed conform to NSObjectProtocol (as you can see here: https://github.com/apple/swift/blob/master/stdlib/public/runtime/SwiftObject.mm).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With