The Secret Life of Classes

A class method may be called by sending a message directly to the name of a class. For example, the familyNames class method of UIFont that I mentioned a moment ago might be called like this:

NSArray* fams = [UIFont familyNames];

Clearly, this is possible because a class is an object (Chapter 2), and the name of the class here represents that object.

You don’t have to do anything to create a class object. One class object for every class your program defines is created for you automatically as the program starts up. (This includes the classes your program imports, so there’s a MyClass class object because you defined MyClass, and there’s an NSString class object because you imported UIKit.h and the whole Cocoa framework.) It is to this class object that you’re referring when you send a message to the name of the class.

Your ability to send a message directly to the bare name of a class is due to a kind of syntactic shorthand. You can use the bare class name only in two ways (and we already know about both of them):

To send a message to
In the expression [UIFont familyNames], the bare name UIFont is sent the familyNames message.
To specify an instance type
In the expression NSString*, the bare name NSString is followed by an asterisk to signify a pointer to an instance of this class.

Otherwise, to speak of a class object, you need to obtain that object formally. One way to do this is to send the class message to a class or instance. For example, [MyClass class] returns the actual class object. Some built-in Cocoa methods expect a class object parameter, whose type is described as Class. To supply this as an argument, you’d need to obtain a class object formally. Take, for example, introspection on an object to inquire what its class is. The isKindOfClass: instance method is declared like this:

- (BOOL)isKindOfClass:(Class)aClass

So that means you could call it like this:

if ([someObject isKindOfClass: [MyClass class]]) // ...

A class object is not an instance, but it is definitely a full-fledged object. Therefore, a class object can be used wherever an object can be used. For example, it can be assigned to a variable of type id:

id classObject = [MyClass class];

You could then call a class method by sending a message to that object, because it is the class object:

id classObject = [MyClass class];
[classObject someClassMethod];

All class objects are also members of the Class class, so you could say this:

Class classObject = [MyClass class];
[classObject someClassMethod];

Get Programming iOS 6, 3rd Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.