id(instancetype)解析、容错处理

instancetype解析:

在构造方法中会看到:

-(instancetype)init{
    /*self 是一个指针,表示当前调用该方法的对象本身*/
    /*super是一个关键字,用来调用父类方法*/
    self=[super init];   //最基本的初始化操作
    if(self){
       //要初始化的内容
    }
}
  • init无法确认是什么类继承了NSObject
  • instancetype前身是id,可以指向任意的对象类型;
  • id的弊端:虽然可表示所有类型,但是一个公共类型,处理不了精准的问题。
    instancetype更加智能,init写在哪个类中,就会自动用该类名来替代instancetype,instancetype只能用在构造方法里的返回类型。

id

  • 动态类型识别(在运行的时候进行,而不是在编译的时候进行)
    动态绑定,运行时确定类型之后才能确定消息是否能被响应
  • 补充:静态类型编译时查错,动态类型方便扩展。

一般用id后要进行容错处理:

容错处理:一般先判断对象类型,再判断能否响应某个方法,最后再执行。

  1. 确定对象类型
  • 判断对象是否是某个类的对象
    if( [value isNumberOfClass:[p1 Class] ] ) { }
  • 判断对象是否是某个类的对象或其子类对象
    if( [value isKindOfClass:[NSObject Class] ] ) { }

注意:NSString NSArray NSDictionary NSNumber
不能判断类的对象,因为它们底层是以“类簇”方式实现的,类方法都是私有子类提供的,本身只是对外暴露一个类。

  1. 判断能否响应方法
    Person *value = [Person new];
    [value length]; 判断能否响应方法
  • 在调用方法前,判断对象能不能响应方法
// SEL action = @selector ( length )
if(value respondsToSelector: @selctor(length)){   
    [value length];
}
else{
    NSLog(@“无法响应该方法”);
}
  • 判断一个类能不能响应某个方法:
if ( [ Person instancesRespondsToSelector:@selector(sayHello) ] ) {
    NSLog(@“Person 类实现了 sayHello方法”);
}
else{
    NSLog(@“Person 类没有实现 sayHello方法”);
}
  • 如果是判断私有方法:
    需要进行隐式调用:
    [ value performSelector: @selector(sayHello) ];

你可能感兴趣的:(id(instancetype)解析、容错处理)