我很难绕过这个概念。我将完全从书中获取引用:
类对象也从层次结构中的上层类继承。但是因为它们没有实例变量(只有实例),所以它们只继承方法。
如果我错了,请纠正我,但是类对象就是这样:
NSString *aString = [[NSString alloc]initWithString:@"abc.."];
本案例中的类对象是*aString
- 到目前为止我是否正确?
令我困惑的是上面引用中的第二句,“但是因为它们没有实例变量(只有实例),所以它们只继承方法。”
我认为对象(在本例中为*aString
)是NSString
类的实例。
上面的第二句意味着一个实例是不同的。这对我没有任何意义。
答案 0 :(得分:6)
你错了。
NSString *aString = [[NSString alloc] initWithString:@"abc..."];
在这一行中,我们从左到右:
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
答案 1 :(得分:3)
在ObjectiveC中,类本身就是对象。
在您的示例中, aString 是一个NSString对象但是 NSString 也是一个对象,它是一个类对象。
类对象具有像这样声明的方法,例如
@interface MyClass : NSObject
{
}
+(void) myClassMethod;
@end
要调用myClassMethod方法,请键入:
[MyClass myClassMethod];
但是没有像C ++或Java那样的静态变量,所以类对象(这里是MyClass)不能包含变量,但MyClass类的实例可以有变量。
因此要恢复NSString是一个类对象,而aString是NSString的实例对象。
答案 2 :(得分:1)
在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
的子类; VacuBob
的任何实例都有自己的uniformColor
实例变量。同样,编译器创建了一个类对象VacuBob
;它也从Bob
类对象继承自Bob
。这意味着VacuBob
类对象也具有方法willShootAtPlayer
。
在你发布的那一行:
... aString = [NSString alloc] ...
这里的类对象实际上是NSString
。您正在调用名为+[NSString alloc]
3 的类方法(类方法由+
表示,而不是-
4 < / SUP>)。当类名用作消息的接收者(括号表达式的前半部分)时,它引用类对象 5 。在这种情况下,NSString
和 aString
都是对象;它们只是两种不同的物体; aString
是一个实例。
Dave DeLong在这个帖子上发表了一篇好文章(特别是图表几乎把所有内容都列出来了);有关更多信息,您还应该在他的iOS书中查看Matt Neuberg对"The Secret Life of Classes"的描述。它描述了类对象的创建,它们的用途,以及它们除了持有方法之外还做的其他事情。
1 这是isa
指针:myBob->isa
是指Bob
类对象。
2 引用类对象的变量的类型为Class
。实例对象的类型是它的类。因此Bob
的类型为Class
,myBob
的类型为Bob *
(即指向对象的指针,其类型为Bob
)。变量类型和对象类型之间的区别可能会引起一些混淆。
3 alloc
的返回值恰好是NSString
的一个实例,您可以在其上调用实例方法initWithString:
4 类方法并行实例方法,它们以类对象本身作为参数调用。由于类对象没有自己的数据,因此类方法的使用可能比其他OO语言更有限;类方法最常用于自动售货实例。
5 当它用于变量声明:NSString * mySting;
时,它是变量类型的名称。