首先需要知道,在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 的命名规则,满足下述命名规则的方法应该返回该方法所在类的实例化对象,这些方法被称为是关联返回类型的方法:
例如:
+ (instancetype)alloc;
- (instancetype)init;
//因此这里alloc和init返回的类型都是NSArray*
NSArray *arr = [[NSArray alloc]init];
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
从定义来看,NSObject* 就是指向NSObject类型的指针了,可以指向任何一个继承了NSObject的对象,感觉和上面的id、instancetype也没有区别。
区别在于NSObject* 是静态数据类型,编译时会进行类型检查。
NSObject*的作用与id一致。
id<NSObject> *就是指该对象的类型可以是任何一个NSObject或继承了NSObject的子类,但该对象必须要遵循<NSObject>协议(奇葩的命名:协议名与类名一样)。简单来说就是它不关心对象是什么类型,只要遵循<NSObject>协议即可。
在定义delegate时常用。