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

后端 未结 8 1497
一向
一向 2020-12-13 00:01

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

[MyClass aClassMethod];

And you can query an instance\'s kind with:

[som         


        
8条回答
  •  时光说笑
    2020-12-13 00:28

    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.

提交回复
热议问题