美文网首页
iOS:SEL与IMP,方法与函数

iOS:SEL与IMP,方法与函数

作者: Liu____ | 来源:发表于2020-06-11 14:23 被阅读0次

    SEL与IMP

    
    #import "ViewController.h"
    #import <objc/message.h>
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //objc调用
        void (^objcBlock)(NSString *) = ^(NSString *abc){
            NSLog(@"objc:%@",abc);
        };
        ((void *(*)(id, SEL,id))(void *)objc_msgSend)(objc_getClass("ViewController"), sel_registerName("test:"),@"objc");
        ((void *(*)(id, SEL,id,id))(void *)objc_msgSend)(self, sel_registerName("test:callBack:"),@"objc",objcBlock);
    
        //通过sel调用
        SEL sel =@selector(test:callBack:);
    //    SEL sel = NSSelectorFromString(@"test:callBack:");
        void (^selBlock)(NSString *) = ^(NSString *abc){
            NSLog(@"sel:%@",abc);
        };
        [self performSelector:@selector(test:callBack:) withObject:@"sel" withObject:selBlock];
        
        //执行imp
        IMP imp = [self methodForSelector:sel];
        void (*func)(id, SEL,id,id) = (void *)imp;
    //    void (*func)(id, SEL,id,id) = (void (*)(id,SEL,id,id))imp;
    
        func(self,@selector(test:callBack:),@"imp",^(NSString *abc){
            NSLog(@"imp:%@",abc);
        });
    }
    + (void)test:(NSString *)test
    {
        NSLog(@"%@",test);
    }
    -(void)test:(NSString *)test callBack:(void (^)(NSString *abc))callback
    {
        NSLog(@"%@",test);
        if (callback) {
            callback(@"123");
        }
    }
    
    
    @end
    
    
    • SEL: 类成员方法的指针,可以理解 @selector()就是取类方法的编号

      通过方法名获取SEL:

       SEL sel =@selector(test:);
       SEL sel = NSSelectorFromString(@"test:");  
      

      通过SEL获取方法名Str:

       NSString *methodStr = NSStringFromSelector(@selector(test:));
      

      根据SEL来调用方法:

      [self performSelector: @selector(test:) withObject:nil];
      
    • IMP: 函数的指针
      通过SEL获得IMP

      IMP imp = [Obj methodForSelector: @selector(test:)];
      

      执行IMP

      void (*func)(id, SEL, id) = (void *)imp;  
      func(self, @selector(test:),@"123");
      
    • IMP和SEL关系:
      每一个继承于NSObject的类都能自动获得runtime的支持。在这样的一个类中,有一个isa指针,指向该类定义的数据结构体,这个结构体是由编译器编译时为类(需继承于NSObject)创建的.在这个结构体中有包括了指向其父类类定义的指针以及 Dispatch table. Dispatch table是一张SEL和IMP的对应表。也就是说方法编号SEL最后还是要通过Dispatch table表寻找到对应的IMP,IMP就是一个函数指针,然后执行这个方法。
      在OC种中,SEL和IMP之间的关系,好像是一个书本的”目录“,SEL是方法编号,就像”标题“一样,IMP是方法实现的真实地址,就像”页码“一样,他们是一一对应的关系。

      SEL-IMP.png

    关于SEL文章:
    https://blog.csdn.net/fengsh998/article/details/8614486

    iOS方法与函数

    • 方法:
      1,在@interface和@end之间声明,在@implementation和@end之间实现,类方法以+号开头;对象方法以-号开头

      #import "ViewController.h"
      @interface ViewController ()
      + (void) test1;
      - (void) test2;
      @end
      
      @implementation ViewController
      + (void) test1
      {
          NSLog(@"test1");
      }
      - (void) test2
      {
          NSLog(@"test2");
      
      }
      - (void)viewDidLoad {
          [super viewDidLoad];
          [ViewController test1];
          [self test2];
      }
      @end
      
      

      2,类方法由类来调用;对象方法由对象来调用
      3,方法归类、对象所有

    • 函数:
      1,函数能写在文件中的任意位置(@interface和@end之间除外)

      void test3()
      {
          NSLog(@"test3");
      }
      

      2,函数调用不依赖于对象

      test3();
      

      3,函数归文件所有。

    C函数调用OC方法
    https://blog.csdn.net/u010858147/article/details/52571939

    相关文章

      网友评论

          本文标题:iOS:SEL与IMP,方法与函数

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