iOS>“ID”与NSObject
与“typesid
相比,“多态”方式中的Object
与NSObject *
有什么区别?
以什么方式:
NSString* aString = @"Hello"; id anObj = aString;
不同于:
NSString* aString = @"Hello"; NSObject* anObj = aString;
id
是Objective-C中用来表示“某种对象”的一个特殊关键字。它不包含isa
指针( isa
,它允许对象访问它的类,并且通过这个类来访问它所inheritance的所有类),所以你会丢失有关对象的编译时信息。
NSString* aString = @"Hello"; id anObj = aString;
NSObject
包含isa
指针。
NSString* aString = @"Hello"; NSObject* anObj = aString;
从Objective-C是一个dynamic语言
考虑下面的代码:
id someObject = @"Hello, World!"; [someObject removeAllObjects];
在这种情况下,someObject将指向一个NSString
实例,但是编译器对这个实例一无所知,除了它是某种对象。 removeAllObjects
消息是由一些Cocoa或Cocoa Touch对象(如NSMutableArray
)定义的,所以编译器不会抱怨,即使这个代码会在运行时产生一个exception,因为NSString对象不能响应removeAllObjects
。
重写代码以使用静态types:
NSString *someObject = @"Hello, World!"; [someObject removeAllObjects];
意味着编译器现在会产生一个错误,因为removeAllObjects
没有在它知道的任何公共NSString
接口中声明。
id
是通用的。 通过使用id
你告诉编译器,你将在稍后填写使用的细节。 编译器假定你所拥有的任何代码都是正确的,并不会提醒你任何事情。 在运行时进行检查以validation你正在尝试做什么,如果你的代码是错误的,你会得到一个exception。
NSObject
是特定的。 通过使用NSObject
你正在告诉编译器到底是什么对象。 当你尝试调用它的方法时,它们将被检查NSObject
理解的内容。 如果你犯了一个错误,你会得到编译时错误。
所有这一切说,你可以在两种情况下投入到另一个类的types。
你关心的是你将来要做什么。 一般来说,使用NSObject
没有任何好处。
- id是一个语言关键字,但NSObject是目标c中的基类。
- 对于id,你不需要对对象进行types转换。 但是对于NSObject,你必须把它转换成NSObject。
- 一个id对象可以用来调用任何方法。 但NSObject对象可以用来调用NSObject中定义的特定方法
使用id时,可以发送任何已知的消息,当使用NSObject *时,只能发送NSObject声明的消息(不是任何子类的方法),否则会产生警告。