Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Does AnyObject Conform to NSObjectProtocol?

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?

like image 867
JAL Avatar asked Apr 25 '16 22:04

JAL


People also ask

What is [anyobject] in Objective-C?

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.

What is nsobjectprotocol in Swift?

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.

What is the NSObject protocol in Cocoa?

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.


1 Answers

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).

like image 91
matt Avatar answered Nov 21 '22 07:11

matt