iOS - id与NSObject*与id

iOS - id与NSObject*与id<NSObject>_第1张图片
图片源于网络

id:

  • 简单地申明了指向对象的指针,没有给编译器任何类型信息,因此,编译器不会做类型检查。

  • 你可以发送任何信息给id类型的对象(例如: +alloc返回id类型,但调用[[Foo alloc] init]不会产生编译错误)

  • 对于一些不想或者不能进行类型检查的地方,可以使用id。比如在集合(array, collection)类型中,比如在一些你并不知道方法的返回类型的地方(比如alloc),比如我们经常声明delegate为id类型,在运行的时候再使用respondToSelector:来进行检查。

typedef struct objc_class *Class;
typedef struct objc_object {
    Class isa;
} *id;

NSObject *:

  • 申明了指向NSObject类型对象的指针,编译器会做类型检查

id

  • 它也是一个是指针,它要求它指向的类型要实现NSObject protocol

  • NSObject类实现了NSOject接口,所以id可以指向NSObject的对象。

@interface NSObject  {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
    Class isa  OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}
  • NSProxy类实现了NSOject接口,所以id可以指向NSProxy的对象。
@interface NSProxy  {
    Class   isa;
}

instancetype

  • 关键字instancetype,表示某个方法返回的未知类型的Objective-C对象

  • 可以使那些非关联返回类型的方法返回所在类的类型

@interface NSArray  
+ (id)constructAnArray;  
+ (instancetype)constructAnArray1;  
@end 

[NSArray constructAnArray];  
//根据Cocoa的方法命名规范,得到的返回类型就和方法声明的返回类型一样,是id。
[NSArray constructAnArray1]; 
//根据Cocoa的方法命名规范,得到的返回类型和方法所在类的类型相同,是NSArray*!
  • instancetype与id的区别

    ①instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;

    ②instancetype只能作为返回值,不能像id那样作为参数

  • 在instancetype有效的情况下,应该尽量去使用instancetype。参考 “Use instancetype whenever it's appropriate, which is whenever a class returns an instance of that same class.”

  • 官方文档

In your code, replace occurrences of id as a return value with instancetype where appropriate. This is typically the case for init methods and class factory methods. Even though the compiler automatically converts methods that begin with “alloc,” “init,” or “new” and have a return type of id to return instancetype, it doesn’t convert other methods. Objective-C convention is to write instancetype explicitly for all methods.

参考

id、NSObject *、id、instancetype的区别

iOS中id - NSObject* - id的区别

你可能感兴趣的:(iOS - id与NSObject*与id)