Why do we have to do [MyClass class] in Objective-C?

Ooooh… fun question. The answer is a c-ism.

Consider:

@interface MyClass : NSObject
@end
@implementation MyClass
@end

Now, say you have:

...
MyClass *m = nil;
...

In that context, the compiler sees MyClass as a type definition. The * says that the variable m is a pointer to a hunk o' memory that contains one (or many -- don't forget your C pointer-fu) MyClass instances.

In other words, MyClass is a type.

But, in the context of something like:

[someInstance isKindOfClass: x ];

x must be an rvalue or, in human terms, the value of an expression. A type, however, cannot be used as an rvalue.

That [MyClass class] works is actually a bit of a hack, both in the language and the compiler in that the grammar specifically allows a type name to be the message receiver (to be the target of a method call).

And, as a matter of fact, you can do:

typedef MyClass Foo;
....
[MyClass class];
[Foo Class];

It’ll all work. However, you can’t do the following but the error message is illuminating:

[NSUInteger class];

error: ‘NSUInteger’ is not an Objective-C class name or alias


Now, why not special case it everywhere as a bare name?

That colludes type names and rvalues and you quickly end up having to swallow something like [foo isKindOfClass: (MyClass)]; while barfing on [foo isKindOfClass: (MyClass *)]; which then encroaches upon typecasting territory in a rather uncomfortable fashion.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)