iOS>"id"与NSObject

Oha*_*gev 8 objective-c nsobject ios

是否有涉及的之间的差异Object与类型"多态"的方式id不是NSObject *

以什么方式:

NSString* aString = @"Hello";
id anObj = aString;
Run Code Online (Sandbox Code Playgroud)

不同于:

NSString* aString = @"Hello";
NSObject* anObj = aString;
Run Code Online (Sandbox Code Playgroud)

Par*_*fna 10

id是Objective-C中使用的一个特殊关键字,意思是"某种对象."它不包含isa指针(isa给对象访问它的类,并通过类,它来自它继承的所有类),所以你输了有关该对象的编译时信息.

NSString* aString = @"Hello";
id anObj = aString;  
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

NSObject包含isa指针.

NSString* aString = @"Hello";
NSObject* anObj = aString;
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

来自Objective-C是一种动态语言

请考虑以下代码:

id someObject = @"Hello, World!";
[someObject removeAllObjects];
Run Code Online (Sandbox Code Playgroud)

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

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

NSString *someObject = @"Hello, World!";
[someObject removeAllObjects];
Run Code Online (Sandbox Code Playgroud)

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


Wai*_*ain 6

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

NSObject是具体的.通过使用NSObject你告诉编译器确切的对象是什么.当您尝试在其上调用方法时,将检查它们的NSObject理解.如果出错,您将收到编译时错误.

所有这一切,你可以在两种情况下转换为另一种类型.

您的关注点是将来您将要参考的内容.一般来说,使用NSObject没有任何好处.

  • 在讨论`id`时我会避免使用'generic'这个词,因为泛义意味着与其他几种语言中的'后期绑定对象'完全不同(例如[c#](http://msdn.microsoft.com/en-) us/library/ms379564(v = vs.80).aspx)和[java](http://en.wikipedia.org/wiki/Generics_in_Java)).来自其中一种语言的人可能会很容易混淆,并希望从"id"中获得相同类型的行为 (2认同)