iOS> “id”与NSObject

时间:2013-10-28 12:06:19

标签: ios objective-c nsobject

“多态”方式Object与类型id的关联与NSObject *的关联是否存在差异?

以什么方式:

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

不同于:

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

4 个答案:

答案 0 :(得分:10)

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

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

enter image description here

NSObject包含isa指针。

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

enter image description here

来自Objective-C Is a Dynamic Language

请考虑以下代码:

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

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

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

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

表示编译器现在会生成错误,因为removeAllObjects未在它知道的任何公共NSString接口中声明。

答案 1 :(得分:6)

id是通用的。通过使用id,您告诉编译器您将在以后填写有关使用的详细信息。编译器假定您拥有的任何代码都是正确的,并且不会向您发出任何警告。在运行时,会进行检查以验证您要执行的操作,如果您的代码错误,您将收到异常。

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

所有这一切,你可以在两种情况下进行转换以获得另一种类型。

您的关注点是您将来要参考的内容。通常,使用NSObject没有任何好处。

答案 2 :(得分:1)

  1. id 是一种语言关键字,但 NSObject 是目标c中的基类。
  2. 对于id,您不需要对对象进行类型转换。但     对于NSObject,你必须将它强制转换为NSObject。
  3. 一个id对象     可用于调用任何方法。但是NSObject对象可以用来     仅调用NSObject
  4. 中定义的特定方法

答案 3 :(得分:0)

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