关于runtime的一些简单理解

1.消息发送
OC:运行时机制,消息机制是运行时机制最重要的机制
消息机制:任何方法调用,本质都是发送消息

SEL:方法编号,根据方法编号就可以找到对应方法实现
Person *p = [[Person alloc] init];
[p performSelector:@selector(eat)];
// 让p发送消息
// objc_msgSend(p, @selector(eat));
// objc_msgSend(p, @selector(run:),10);带参数的消息
这是消息发送的对象方法。

// 获取类对象
Class personClass = [Person class];
[personClass performSelector:@selector(eat)];
// 运行时
objc_msgSend(personClass, @selector(eat));
这是消息发送的类方法。

2.方法交换
// 交换方法实现,方法都是定义在类里面
// class_getMethodImplementation:获取方法实现
// class_getInstanceMethod:获取对象
// class_getClassMethod:获取类方法
// IMP:方法实现

// Class:获取哪个类方法
// SEL:获取方法编号,根据SEL就能去对应的类找方法
Method imageNameMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));

// xmg_imageNamed
Method xmg_imageNamedMethod = class_getClassMethod([UIImage class], @selector(xmg_imageNamed:));

// 交换方法实现
method_exchangeImplementations(imageNameMethod, xmg_imageNamedMethod);

实列:

  • (UIImage *)xmg_imageNamed:(NSString *)imageName
    {
    // 1.加载图片
    UIImage *image = [UIImage xmg_imageNamed:imageName];

    // 2.判断功能
    if (image == nil) {
    NSLog(@"加载image为空");
    }

    return image;
    }
    这样就实现了两个方法的交换。

3.动态添加方法
// performSelector:动态添加方法,声明一个类,并不提供eat:这个方法
Person *p = [[Person alloc] init];
[p performSelector:@selector(eat:) withObject:@111];
在Person类中,
// 动态添加方法,首先实现这个resolveInstanceMethod
// resolveInstanceMethod调用:当调用了没有实现的方法没有实现就会调用resolveInstanceMethod
// resolveInstanceMethod作用:就知道哪些方法没有实现,从而动态添加方法
// sel:没有实现方法

  • (BOOL)resolveInstanceMethod:(SEL)sel
    {
    // NSLog(@"%@",NSStringFromSelector(sel));

    // 动态添加eat方法
    if (sel == @selector(eat:)) {

      /*
       cls:给哪个类添加方法
       SEL:添加方法的方法编号是什么
       IMP:方法实现,函数入口,函数名
       types:方法类型
       */
      // @:对象 :SEL
      class_addMethod(self, sel, (IMP)aaaa, "v@:@");
      // 处理完
      return YES;
    

    }
    return [super resolveInstanceMethod:sel];
    }

声明一个C语言的函数来动态添加
void aaaa(id self, SEL _cmd, id param1)
{
NSLog(@"调用eat %@ %@ %@",self,NSStringFromSelector(_cmd),param1);
}

4.分类动态添加属性
列如给NSObject添加一个name属性

  • (void)setName:(NSString *)name
    {
    // 添加属性,跟对象
    // 给某个对象产生关联,添加属性
    // object:给哪个对象添加属性
    // key:属性名,根据key去获取关联的对象 ,void * == id
    // value:关联的值
    // policy:策越
    objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    // _name = name;
    }

  • (NSString *)name
    {
    return objc_getAssociatedObject(self, @"name");
    }

你可能感兴趣的:(关于runtime的一些简单理解)