美文网首页
id、instancetype、NSObject *和id

id、instancetype、NSObject *和id

作者: 牛奶红茶 | 来源:发表于2021-03-17 09:32 被阅读0次

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类或其子类,当然,实例的具体类型也要在运行时才能确定(面向对象的三大特性之:多肽)

->静态类型在编译时就知道变量的类型,这样在编译的时候就可以访问对象的属性和方法,如果访问了不属于静态类型的属性和方法,那么编译期就会报错,而动态数据类型在编译时并不知道变量的真实类型,只有在运行时的时候才知道它的真实类型,因此编译时候如果访问了不属于动态类型的属性和方法,编译器不会报错,但是会导致运行时的错误,这也是动态数据类型的弊端

---

相关文章

网友评论

      本文标题:id、instancetype、NSObject *和id

      本文链接:https://www.haomeiwen.com/subject/swddcltx.html