Objective-C中的类对象和实例变量



我很难理解这个概念。我会引用这本书中的话:

类对象也继承自层次结构中它们上面的类。但因为它们没有实例变量(只有实例有),所以它们只继承方法。

如果我错了,请纠正我,但类对象应该是这样的:

NSString *aString = [[NSString alloc]initWithString:@"abc.."];

这种情况下的类对象是*aString——到目前为止我是正确的吗?

让我困惑的是上面引用的第二句话,"但因为它们没有实例变量(只有实例有),所以它们只继承方法。"

我认为对象(在本例中为*aString)是NSString类的实例。上面的第二句话暗示了一个例子是不同的。这对我来说毫无意义。

你错了。

NSString *aString = [[NSString alloc] initWithString:@"abc..."];

在这一行中,我们从左到右依次为:

  • A型:NSString *
  • 变量名:aString
  • 任务
  • Class:NSString
  • 类方法的调用:+alloc
  • 对类方法的返回值调用实例方法:-initWithString:
  • 作为参数传递给实例方法的对象:@"abc..."

在Objective-C中,Class实际上是一种对象。您可以以与实例相同的许多方式与它们交互,但由于它们是"类",因此它们不能具有实例变量(因为根据定义,实例变量仅用于实例)。Classes只有方法。它们继承自其他Classes,这就是对象继承的实现方式。

有关这方面的更多信息,请查看Greg Parker的这篇很棒的博客文章:http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html

在ObjectiveC中,类本身就是对象。

在您的示例中,aString是一个NSString对象,但NSString也是一个对象,它是一个类对象。

类对象有这样声明的方法,例如

@interface MyClass : NSObject
{
}
+(void) myClassMethod;
@end

要调用myClassMethod方法,请键入:

[MyClass myClassMethod];

但是没有像C++或Java中那样的静态变量,所以类对象(此处为MyClass)不能包含变量,但类MyClass的实例可以包含变量。

因此,恢复NSString是一个类对象,而aString是NSString的实例对象。

在Objective-C中,有一些实例,它们是您创建和使用的对象,还有一些(半隐藏)对象,它们是类对象,由编译器创建。类对象是存储该类的方法的位置;每个实例只保存自己的数据(即实例变量)。

Bob * myBob = [[Bob alloc] init];

这里,myBob就是一个例子。每个实例都有一个对其类对象的引用1当您在实例上调用方法时:

[myBob frogBlastTheVentCore];

运行时在类对象中查找该方法,然后使用实例和实例的数据来执行该方法。这是Obj-C中对象的基本组织:实例对象保存数据并引用其类对象,这些类对象保存方法。每个类只有一个类对象;该类的所有实例都具有对同一类对象的引用。

一个类(暂时被认为是"类型"而不是对象2)被认为是从另一个类继承:

@interface Bob : NSObject {
    NSColor * uniformColor;        
}
+ (BOOL) willShootAtPlayer;
- (void) frogBlastTheVentCore;
@end
@interface VacuBob : Bob {}
@end

这里,VacuBobBob的一个子类;CCD_ 17的任何实例都有其自己的CCD_。同样地,存在由编译器创建的类对象VacuBob;它也继承自CCD_ 20——来自CCD_ 21类对象。这意味着VacuBob类对象也具有方法willShootAtPlayer

在你发布的行中:

... aString = [NSString alloc] ...

类对象在这里实际上是CCD_ 24。您正在调用名为+[NSString alloc]3类方法(类方法由+而不是-4表示)。当类名被用作消息的接收者(括号中表达式的前半部分)时,它指的是类对象5。在这种情况下,那么NSStringaString都是对象;它们只是两种不同的物体;CCD_ 30就是一个例子。

Dave DeLong链接了一篇关于这方面的好帖子(尤其是图表几乎列出了所有内容);欲了解更多信息,您还可以查看Matt Neuberg在其iOS书中对"课堂的秘密生活"的描述。它描述了类对象的创建、它们的用途,以及它们除了持有方法之外所做的其他事情。


1这是isa指针:myBob->isa指的是Bob类对象

2引用类对象的变量的类型为Class。实例对象的类型就是它的类。因此,Bob的类型是ClassmyBob的类型是Bob *(即指向对象的指针,其类型为Bob)。变量类型和对象类型之间的区别可能会在这里引起一些混淆。

3alloc的返回值恰好是NSString的一个实例,在该实例上调用实例方法initWithString:

4类方法与实例方法并行,因为它们是用类对象本身作为参数来调用的。由于类对象没有自己的数据,类方法的使用可能比其他OO语言更受限制;类方法最常用于自动售货实例。

5当它用于变量NSString * mySting;的声明时,它是变量类型的名称。

相关内容

  • 没有找到相关文章

最新更新