我很难理解这个概念。我会引用这本书中的话:
类对象也继承自层次结构中它们上面的类。但因为它们没有实例变量(只有实例有),所以它们只继承方法。
如果我错了,请纠正我,但类对象应该是这样的:
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
这里,VacuBob
是Bob
的一个子类;CCD_ 17的任何实例都有其自己的CCD_。同样地,存在由编译器创建的类对象VacuBob
;它也继承自CCD_ 20——来自CCD_ 21类对象。这意味着VacuBob
类对象也具有方法willShootAtPlayer
。
在你发布的行中:
... aString = [NSString alloc] ...
类对象在这里实际上是CCD_ 24。您正在调用名为+[NSString alloc]
3的类方法(类方法由+
而不是-
4表示)。当类名被用作消息的接收者(括号中表达式的前半部分)时,它指的是类对象5。在这种情况下,那么NSString
和aString
都是对象;它们只是两种不同的物体;CCD_ 30就是一个例子。
Dave DeLong链接了一篇关于这方面的好帖子(尤其是图表几乎列出了所有内容);欲了解更多信息,您还可以查看Matt Neuberg在其iOS书中对"课堂的秘密生活"的描述。它描述了类对象的创建、它们的用途,以及它们除了持有方法之外所做的其他事情。
1这是isa
指针:myBob->isa
指的是Bob
类对象。
2引用类对象的变量的类型为Class
。实例对象的类型就是它的类。因此,Bob
的类型是Class
,myBob
的类型是Bob *
(即指向对象的指针,其类型为Bob
)。变量类型和对象类型之间的区别可能会在这里引起一些混淆。
3alloc
的返回值恰好是NSString
的一个实例,在该实例上调用实例方法initWithString:
4类方法与实例方法并行,因为它们是用类对象本身作为参数来调用的。由于类对象没有自己的数据,类方法的使用可能比其他OO语言更受限制;类方法最常用于自动售货实例。
5当它用于变量NSString * mySting;
的声明时,它是变量类型的名称。