-
id是通用的。通过使用id您告诉编译器您将在以后填写有关使用的详细信息。编译器假定您拥有的任何代码都是正确的,并且不会向您发出任何警告。在运行时,会进行检查以验证您要执行的操作,如果您的代码错误,您将收到异常。
-
NSObject是具体的。通过使用NSObject你告诉编译器确切的对象是什么。当您尝试在其上调用方法时,将检查它们的NSObject理解。如果出错,您将收到编译时错误。
id
是Objective-C中使用的一个特殊关键字,意思是“某种对象”。id 指向的对象并不全是 NSObject 的子类。它不包含isa
指针(isa
给对象访问它的类,并通过类,它来自它继承的所有类),所以你输了有关该对象的编译时信息。
NSString* aString = @"Hello";
id anObj = aString;
NSObject
包含isa
指针。
请考虑以下代码:
id someObject = @"Hello, World!";
[someObject removeAllObjects];
在这种情况下,someObject将指向一个NSString
实例,但除了它是某种对象之外,编译器对该实例一无所知。所述removeAllObjects
消息是由一些可可或可可触摸对象(如定义的NSMutableArray
),从而,编译器不抱怨,即使该代码将在运行时生成异常,因为一个NSString对象不能响应removeAllObjects
。
重写代码以使用静态类型:
NSString *someObject = @"Hello, World!";
[someObject removeAllObjects];
意味着编译器现在将生成错误,因为removeAllObjects
它没有在NSString
它知道的任何公共接口中声明。
- id<NSObject>
将一个对象声明为 id<NSObject> ,意味着编译器不对其作任何类型检查,但是这个对象所属的类默认实现名为 NSObject 的protrol(是的,也有一个协议叫 NSObject )。其实,在实际操作中,我们往往不会去关心一个对象的所属的类,而是这个对象会响应什么方法,id<NSObject> 表明了这个指针指向了一个实现了 NSObject 协议的方法的类的对象。
网友评论