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

时间:2011-06-24 15:09:14

标签: objective-c class object instance instance-variables

我很难绕过这个概念。我将完全从书中获取引用:

  

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

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

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

本案例中的类对象是*aString - 到目前为止我是否正确?

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

我认为对象(在本例中为*aString)是NSString类的实例。 上面的第二句意味着一个实例是不同的。这对我没有任何意义。

3 个答案:

答案 0 :(得分:6)

你错了。

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

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

  • 类型:NSString *
  • 变量名称:aString
  • 作业
  • ClassNSString
  • 调用类方法:+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

此处,VacuBobBob的子类; 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的类型为ClassmyBob的类型为Bob *(即指向对象的指针,其类型为Bob)。变量类型和对象类型之间的区别可能会引起一些混淆。

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

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

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

相关问题