iOS中SEL类型

830 阅读2分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

什么是SEL类型

  • SEL类型代表着方法的签名,在类对象的方法列表中存储着该签名与方法代码的对应关系

  • 每个类的方法列表都存储在类对象中

  • 每个方法都有一个与之对应的SEL类型的对象

  • 根据一个SEL对象就可以找到方法的地址,通过方法的地址就可以调用方法


SEL类型的定义

typedef struct objc_selector *SEL

SEL对象的创建

  • 将test方法包装成SEL对象

    SEL s = @selector(test);
    
  • 将一个字符串方法test转换成为SEL对象

    SEL s = NSSelectorFromString(@"test");
    

SEL对象其他用法

  • SEL对象转换为NSString对象  

    NSString *str = NSStringFromSelector(@selector(test));
    
  • 调用对象p的test方法

    [p performSelector:@selector(test)];
    
    • 首先把 test 这个方法名包装成SEL类型的对象
    • 根据SEL类型找到该类的类对象
    • 在类对象的方法列表中找对应的该方法,找到则执行该代码
    • 如果没有找到,则根据类对象上的父类对象指针去父类的类对象的方法列表中查找
    • 如果找到了则执行,如果依然没有找到,一直往上找,直到基类(NSObject),如果都没有找到就报错

    注意:
    在整个操作中有缓存,第一次在方法列表中是一个一个的找,如果找到对应方法,那么就会将该方法放入缓存,之后再用到的时候就直接使用


SEL类型的作用

  • 配合对象、类来检查对象、类中有没有实现一个方法

    注:
    如果通过对象调用该方法,则判断对象方法的实现
    如果通过类调用该方法,则判断有没有类方法的实现

    BOOL flag = [p respondsToSelector:test];
    BOOL flag = [Person respondsToSelector:test];
    
  • 配合对象或者类来调用某一个SEL方法

    //无参数
    SEL sel = @selector(demo);
    [p performSelector:sel];
    
    //有一个参数
    SEL sel = @selector(demo:);
    [p performSelector:sel withObject:@"str"];
    
    //有俩个参数
    SEL sel = @selector(demo: withString:);
    [p performSelector:sel withObject:@"str" withObject:@"str1"];
    
    
  • 配合对象将SEL类型作为方法的形参

    Car *c = [Car new];
    SEL sel = @selector(run);
    Person *p = [Person new];
    [p makeObjct:c withSel:sel];