代码之家  ›  专栏  ›  技术社区  ›  dreamlax

为什么我们必须在Objective-C中执行[MyClass]?

  •  44
  • dreamlax  · 技术社区  · 15 年前

    [MyClass aClassMethod];
    

    您可以通过以下方式查询实例的种类:

    [someInstance isKindOfClass:[MyClass class]];
    

    但是,我们为什么要这么做 [MyClass class] MyClass 这样地:

    [someInstance isKindOfClass:MyClass];
    

    类名 作为接收器(指针类型)而不是作为参数?这是解析语言的限制吗?或者是编译器的限制?

    8 回复  |  直到 15 年前
        1
  •  42
  •   bbum    15 年前

    考虑:

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

    现在,假设你有:

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

    在这种情况下,编译器会看到 MyClass 作为类型定义。这个 * m pointer to a hunk o' memory that contains one (or many -- don't forget your C pointer-fu) MyClass instances .

    换句话说, 类名

    但是,在这样的背景下:

    [someInstance isKindOfClass: x ];
    

    x 必须是右值,或者用人类的术语来说, 表达式的值 . 但是,类型不能用作r值。

    那个 [MyClass class] works实际上在语言和编译器方面都有点像黑客,因为语法特别允许类型名作为消息接收者(作为方法调用的目标)。

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

    一切都会成功的。但是,您不能执行以下操作 错误消息显示:

    [NSUInteger class];
    


    现在,为什么不特例它到处作为一个赤裸裸的名字?

    它将类型名和r值合二为一,很快你就不得不吞下类似的东西 [foo isKindOfClass: (MyClass)]; [foo isKindOfClass: (MyClass *)];

        2
  •  7
  •   Dave DeLong    15 年前

    很有趣。

    在Objective-C中,类名有两个角色,作为数据类型和类对象。作为数据类型名称,可以执行以下操作:

    MyClass *anObject;
    

    作为类对象,类名只能作为消息接收方代表类对象。 这就是为什么你要用

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

    然而,我不认为这个答案能满足你的需要。对我来说,答案是,“是的,你想要的是合理的。但说明书上说的是另一种方式”。

    参考文献: The Objective-C Programming Language Page 32, section: "Class Names in Source Code" .

        3
  •  2
  •   Jared Pochtar    15 年前

    @约翰和@ryanprayogo——你们都大错特错了。MyClass是一个类,也是一个对象,但不是从NSObject继承的。Objective-C的这种方式有点奇怪,但如果充分解释的话,它实际上非常出色(参见 here ). 不过,这里的答案正如@yehnan所说,类名可以是声明器和强制转换的类型名,也可以是消息的接收者。实施 [MyClass class] 能够 支持将其作为参数传递,尽管它根本不支持。

        4
  •  1
  •   John Biesnecker    15 年前

    我的第一眼回答是因为[MyClass]返回一个class类型的对象,而MyClass不从class继承。。。

        5
  •  1
  •   Rob Napier    15 年前

    Class 当它是一个参数而不仅仅是一个消息的目标时。但是在编译器中并没有太多的要求增加这种复杂性(翻译:速度较慢,更难检测到编码错误)。你不应该给那些回来的东西打电话 等级 respondsToSelector: ). 因此,对于这种罕见的事件,以这种方式使编译器复杂化没有多大意义。

        6
  •  -1
  •   OscarRyz    15 年前

    因为什么 isKindOfClass expected是一个“类”,这就是调用返回的内容: [MyClass class]

        7
  •  -1
  •   Steve Weller    15 年前

    我认为MyClass实际上是一个元类。您向它发送class消息以获取实际的类(class类型)。

        8
  •  -2
  •   OscarRyz    15 年前

    MyClass 不是类型 Class .

    [MyClass class] 等级 .

    java.lang.String 不是类型 java.lang.Class

    java.lang.String.getClass() 属于类型 java.lang.Class类

    推荐文章