I am having problem understanding this part of “Testing Class Equality” which is defined in apple guide.
In a dynamically-created subclass, the class method is typically overridden such that the subclass masquerades as the class it replaces. When testing for class equality, you should therefore compare the values returned by the class method rather than those returned by lower-level functions. Put in terms of API, the following inequalities pertain for dynamic subclasses:
[object class] != object_getClass(object) != *((Class*)object)You should therefore test two classes for equality as follows:
if ([objectA class] == [objectB class]) { //...
There are situations in which people add new classes at runtime. One example is Key Value Observing: when you observe an object the Foundation framework creates a new subclass of the observed object’s class. This dynamic class behaves in the same way as its superclass, but adds KVO notifications to all of its mutator methods.
The passage you quoted says that the Objective-C runtime can tell this new class apart from the original class. However, because it’s just an implementation detail of the way KVO is built, you shouldn’t know or care about it. The developers therefore overrode the
-classmethod of their new class, to pretend that objects were still members of the original class.If you want to check whether two objects are of the same class, you must therefore compare the results of their
-classmethods (which take tricks like KVO into account), instead of using runtime functions.Here’s an example:
You see that all I’m doing is creating two objects, telling one of them to observe the other, then finding out what their classes are. Here are the results:
So as the documentation suggests, it’s only the first case (where we compare
-class) that does anything the application code could reasonably expect. The other two ways of finding out the class – asking the runtime, and casting the object pointer to aClass *– both give away implementation details about how KVO has changed the class from underneath us, and mean that the class comparison now won’t show that the classes are equal.Because other answers and comments are referring to
-isMemberOfClass:and-isKindOfClass:, I’ll cover those points too:-isKindOfClass:is not a test for class equality.[object isKindOfClass: aClass]is true ifobjectis an instance ofaClassor any of its subclasses. Because the passage you’ve quoted is about class equality,-isKindOfClass:is not relevant here. That said, it’s most often the test that you want to be doing in application code. It’s more common to care about the answer to “can I use this object as aFoo?” than “is this object an instance exactly ofFoo?”.-isMemberOfClass:is a test for class equality:[object isMemberOfClass: aClass]is only true if object is an instance ofaClass. This test is done using the result of the-classmethod, which means that in this examplemodelwill test positive for[model isMemberOfClass: [NSObject class]].