iOS开发-id、instancetype、NSObject *和id<NSObject> *的区别

    xiaoxiao2025-01-13  16

    首先需要知道,在cocoa的开发环境里,NSObject是所有类的根类。

    1、id

    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; }

    2、instancetype

    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的正确使用姿势

    3、NSObject *

    @interface NSObject <NSObject> { Class isa OBJC_ISA_AVAILABILITY; }

    从定义来看,NSObject* 就是指向NSObject类型的指针了,可以指向任何一个继承了NSObject的对象,感觉和上面的id、instancetype也没有区别。

    区别在于NSObject* 是静态数据类型,编译时会进行类型检查。

    NSObject*的作用与id一致。

    4、id<NSObject> *

    id<NSObject> *就是指该对象的类型可以是任何一个NSObject或继承了NSObject的子类,但该对象必须要遵循<NSObject>协议(奇葩的命名:协议名与类名一样)。简单来说就是它不关心对象是什么类型,只要遵循<NSObject>协议即可。

    在定义delegate时常用。

    最新回复(0)