10

Object以“多态”方式与类型关联与idas之间有区别NSObject *吗?

以什么方式:

NSString* aString = @"Hello";
id anObj = aString;

不同于:

NSString* aString = @"Hello";
NSObject* anObj = aString;
4

4 回答 4

11

id是 Objective-C 中使用的一个特殊关键字,表示“某种对象”。它不包含isa指针(isa,使对象可以访问其类,并通过该类访问它所继承的所有类),因此您会丢失有关该对象的编译时信息。

NSString* aString = @"Hello";
id anObj = aString;  

在此处输入图像描述

NSObject包含isa指针。

NSString* aString = @"Hello";
NSObject* anObj = aString;

在此处输入图像描述

Objective-C 是一门动态语言

考虑以下代码:

id someObject = @"Hello, World!";
[someObject removeAllObjects];

在这种情况下, someObject 将指向一个NSString实例,但编译器对该实例一无所知,除了它是某种对象之外。该removeAllObjects消息由一些 Cocoa 或 Cocoa Touch 对象(例如NSMutableArray)定义,因此编译器不会抱怨,即使此代码会在运行时生成异常,因为 NSString 对象无法响应removeAllObjects

重写代码以使用静态类型:

NSString *someObject = @"Hello, World!";
[someObject removeAllObjects];

意味着编译器现在将生成一个错误,因为它没有在它知道removeAllObjects的任何公共接口中声明。NSString

于 2013-10-28T12:35:43.103 回答
7

id是通用的。通过使用id,您告诉编译器您稍后将填写有关使用的详细信息。编译器假定您拥有的任何代码都是正确的,并且不会警告您任何事情。在运行时检查以验证您正在尝试做什么,如果您的代码错误,您将获得异常。

NSObject是具体的。通过使用NSObject,您可以准确地告诉编译器对象是什么。当您尝试在其上调用方法时,将根据所NSObject理解的内容检查它们。如果你犯了错误,你会得到编译时错误。

综上所述,您可以在这两种情况下强制转换以获取另一个 Class 类型。

您关心的是您将来要如何处理该参考。一般来说,使用NSObject没有任何好处。

于 2013-10-28T12:12:02.180 回答
1
  1. id是语言关键字,但NSObject是目标 c 中的基类。
  2. 对于 id,您不需要对对象进行类型转换。但是对于 NSObject,您必须将其类型转换为 NSObject。
  3. id 对象可用于调用任何方法。但是 NSObject 对象只能用于调用 NSObject 中定义的特定方法
于 2013-10-28T12:18:53.717 回答
0

使用 id 时,您可以向其发送任何已知消息,而使用 NSObject * 时,您只能向其发送由 NSObject 声明的消息(不是任何子类的方法),否则会产生警告。

于 2013-10-28T12:54:19.937 回答