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

In Objective-C, you can call class methods with:

[MyClass aClassMethod]; 

And you can query the type of instance with:

 [someInstance isKindOfClass:[MyClass class]]; 

But why do we need to [MyClass class] , and not just provide MyClass as follows:

 [someInstance isKindOfClass:MyClass]; 

Is there a reason the compiler is ok when encountering MyClass as a receiver (pointer type) but not as an argument? Is this a limitation for language parsing? Or perhaps a compiler restriction?

+44
objective-c
Jun 24 '10 at 4:19
source share
8 answers

Ohhhh ... funny question. The answer is c-ism.

Consider:

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

Now let's say you have:

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

In this context, the compiler sees MyClass as a type definition. * says the variable m is 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, from a human point of view, the value of an expression. However, the type cannot be used as an rvalue.

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

And essentially you can do:

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

Everything will work. However, you cannot do the following, but the error message lights up:

 [NSUInteger class]; 

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




Now, why not have a special occasion everywhere as a bare name?

This combines type names and rvalues, and you quickly have to swallow something like [foo isKindOfClass: (MyClass)]; while barfing on [foo isKindOfClass: (MyClass *)]; which then encroaches on the simulation territory is rather inconvenient.

+41
Jun 24 '10 at 5:03
source share

Interesting.

In Objective-C, a class name has two roles, both a data type and a class object. As a data type name, you can do things like:

 MyClass *anObject; 

As a class object, a class name can only stand behind a class object as a message receiver. And that is why you should use

 ... isKindOfClass:[MyClass class] ... 

However, I do not think this is an answer that can satisfy your needs. For me, the answer is: "yes, what you want is believable, but the specification says differently."

Reference: Objective-C Language Programming Language Page 32, section: "Class Names in Source Code" .

+7
Jun 24 '10 at 4:35
source share

@John and @ryanprayogo - you are both fundamentally wrong. MyClass is a class that is also an object but not inherited from NSObject. Objective-C looks weird like that, but really brilliant when fully explained (see here ). The answer here, however, is that @yehnan said that the class name can be either a type of name for declarators and casts, or as a receiver for messages. The implementation of [MyClass class] returns self (that is, inside the MyClass method). Also, as @yehnan said, the language could support passing it as an argument, although it just doesn't.

+2
Jun 24 '10 at 4:40
source share

My first glance is because the class [MyClass] returns an object of type Class, and MyClass does not inherit Class ...

+1
Jun 24 '10 at 4:23
source share

@yehnan grabs it well, but I will expand a bit. Yes, the compiler can be changed to automatically convert the class identifier to its applicable Class in those places where it is an argument, and not only when it is an object of the message. But in the compiler there are not many requests for such additional complexity (in translation: slower, more difficult to detect coding errors). You should not name things that return Class very often. If so, then your object model is broken. Checking the class should be the last, desperate approach after everything else has failed (first the correct typing, and then respondsToSelector: . Therefore, for such a rare event, it does not make much sense to complicate the compiler this way.

+1
Jun 24 '10 at 4:50
source share

Because the expected isKindOfClass is a "class" and that is returned from the call: [MyClass class]

-one
Jun 24 '10 at 4:22
source share

I think MyClass is actually a metaclass. You send this class message to get the actual class (of type Class).

-one
Jun 24 2018-10-10T00:
source share

MyClass not of type Class .

[MyClass class] is of type Class .

If you are familiar with Java, the concept is the same.

java.lang.String not of type java.lang.Class

java.lang.String.getClass() is of type java.lang.Class

-2
Jun 24 '10 at 4:29
source share



All Articles