首先需要知道,在cocoa的开发环境里,NSObject是所有类的根类。
id的定义:
typedef struct objc_object { Class isa; } *id;从定义来看,id就是一个isa指针,可以指向任何一个继承了Object(或者NSObject)类的对象,所以id可以指向任何一个cocoa的合法对象,id可以简单理解为一个万能指针。
id是动态数据类型,编译时编译器不会检查id对象的类型,只有在运行时动态检查后会报错。
id可以用于
定义变量;定义方法返回值;定义方法参数。 -(id) loadDataWithThings:(id)things { id anyThing = things; return anyThing; }instancetype意思为实例化,instancetype与和id一样,都可以指向一个继承了Object(或者NSObject)类的对象。
区别在于:instancetype只能作为方法返回值,需要返回该方法所在的类的实例化对象,所以instancetype也被称为关联返回类型。
使用instancetype会在编译时进行类型检查,有利于开发者在编译阶段发现错误。
根据 Cocoa 的命名规则,满足下述命名规则的方法应该返回该方法所在类的实例化对象,这些方法被称为是关联返回类型的方法:
以 alloc 或 new 开头的类方法以 autorelease、init、retain 或 self 开头的实例方法。例如:
+ (instancetype)alloc; - (instancetype)init; //因此这里alloc和init返回的类型都是NSArray* NSArray *arr = [[NSArray alloc]init];instancetype的正确使用姿势
从定义来看,NSObject* 就是指向NSObject类型的指针了,可以指向任何一个继承了NSObject的对象,感觉和上面的id、instancetype也没有区别。
区别在于NSObject* 是静态数据类型,编译时会进行类型检查。
NSObject*的作用与id一致。
id<NSObject> *就是指该对象的类型可以是任何一个NSObject或继承了NSObject的子类,但该对象必须要遵循<NSObject>协议(奇葩的命名:协议名与类名一样)。简单来说就是它不关心对象是什么类型,只要遵循<NSObject>协议即可。
在定义delegate时常用。