1.id
id的定义从定义来看,id的本质就是struct objc_object结构体指针,可以指向任何OC对象,其中OC的基类除了NSObject之外,还有一个NSPoxy虚类,因此,id相比NSObject *指向的对虾那个范围更广泛
id是动态数据类型,编译时编译器不会检查id对象的类型,只有在运行时动态检查后会报错
id可以用于定义变量,定义方法返回值,定义方法参数
2.instancetype
instancetype 意思为实例化,innstancetype与id一样都可以指向一个继承了NSObject类的对象
区别在于:instancetype只能作为方法返回值,需要返回该方法所在的类的实例化对象,所以instancetype也被称为关联返回类型
使用 instancetype会在编译时进行类型检查,有利于开发者在编译阶段发现错误
根据Cocoa的命名规则,满足下述命名规则的方法应该返回该方法所在类的实例对象,这些方法被称为是关联返回类型的方法
->以alloc或new开头的类方法
->以 autorelease,init,retain或self开头的实例方法
3.NSObject *
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
从定义来看,NSObject*就是指向NSObject类型的指针了,可以指向任何一个继承了NSObject的对象
NSObject *是静态数据类型,编译时会进行类型检查,
4. id<NSObject>*
id<NSObject> *就是指该对象的类型可以是任何一个NSObject或继承了NSObject的子类,但该对象必须要遵循<NSObject>协议(协议名与类名一样)。简单来说就是它不关心对象是什么类型,只要遵循<NSObject>协议即可
总结:
-> id是动态数据类型,而NSObject*是静态数据类型,默认情况下所有的数据类型都是静态的
-> id类型的实例在编译阶段不会做类型检查,会在运行时确定,而类NSObject的实例在编译期要做编译检查,保证指针指向是其NSObject类或其子类,当然,实例的具体类型也要在运行时才能确定(面向对象的三大特性之:多肽)
->静态类型在编译时就知道变量的类型,这样在编译的时候就可以访问对象的属性和方法,如果访问了不属于静态类型的属性和方法,那么编译期就会报错,而动态数据类型在编译时并不知道变量的真实类型,只有在运行时的时候才知道它的真实类型,因此编译时候如果访问了不属于动态类型的属性和方法,编译器不会报错,但是会导致运行时的错误,这也是动态数据类型的弊端
---
网友评论