Runtime消息机制,交换方法,动态添加方法,分类添加属性

来源:互联网 发布:watermark软件 编辑:程序博客网 时间:2024/05/17 09:05
Runtime 简称运行时,OC就是运行时机制
// OC:运行时机制,消息机制是运行时机制最重要的机制
//消息机制:任何方法调用,本质都是发送消息

严格检查运行机制设置为no

调用类方法,本质也会将类转化为对象调用其方法

  Person *p = [[Personalloc] init];
 //p发送消息
    objc_msgSend(p,@selector(eat));
    objc_msgSend(p, @selector(run:),10);

//获取类对象
    Class personClass = [Personclass];
// [personClass performSelector:@selector(eat)];
//运行时
    objc_msgSend(personClass, @selector(eat));



Runtime 交换方法(用系统的方法调用,不用每个文件引入分类头文件)
分类里面不能调用父类方法,只能用运行时  
交换方法实现,方法都是定义在类里面
加载类方法中调用(load)
+ (void)load
{

    // 交换方法实现,方法都是定义在类里面
    // class_getMethodImplementation:获取类方法实现
    // class_getInstanceMethod:获取对象方法
    // class_getClassMethod:获取类方法
   
// IMP:方法实现
   
   
// imageNamed
   
// Class:获取哪个类方法
   
// SEL:获取方法编号,根据SEL就能去对应的类找方法
   
Method imageNameMethod = class_getClassMethod([UIImageclass], @selector(imageNamed:));
   
   
// xmg_imageNamed
   
Method xmg_imageNamedMethod = class_getClassMethod([UIImageclass], @selector(xmg_imageNamed:));
   
   
// 交换方法实现
    method_exchangeImplementations(imageNameMethod, xmg_imageNamedMethod);
   
}

+ (UIImage*)xmg_imageNamed:(NSString*)imageName
{
   
// 1.加载图片
   
UIImage *image = [UIImagexmg_imageNamed:imageName];
   
   
// 2.判断功能
   
if (image == nil) {
        NSLog(
@"加载image为空");
    }
   
   
return image;
}



Runtime 动态添加方法
有没有使用performSelector,有没有动态添加过方法
// performSelector:动态添加方法 (运行时才会报错)

//动态添加方法,首先实现这个resolveInstanceMethod
// resolveInstanceMethod调用:当调用了没有实现的方法没有实现就会调用resolveInstanceMethod
// resolveInstanceMethod作用:就知道哪些方法没有实现,从而动态添加方法
// sel:没有实现方法



   Person *p = [[Personalloc] init];
   


#import"Person.h"
//动态添加方法
// [p performSelector:@selector(eat)];
    [p performSelector:@selector(eat:) withObject:@111];

//定义函数
//没有返回值,参数(id,SEL)
// void(id,SEL)
voidaaaa(idself,SEL_cmd,idparam1)
{
   
    NSLog(
@"调用eat %@ %@ %@",self,NSStringFromSelector(_cmd),param1);
}

//默认一个方法都有两个参数,self,_cmd,隐式参数
// self:方法调用者
// _cmd:调用方法的编号

//动态添加方法,首先实现这个resolveInstanceMethod
// resolveInstanceMethod调用:当调用了没有实现的方法没有实现就会调resolveInstanceMethod
// resolveInstanceMethod作用:就知道哪些方法没有实现,从而动态添加方法
// sel:没有实现方法


+ (BOOL)resolveInstanceMethod:(SEL)sel
{
//    NSLog(@"%@",NSStringFromSelector(sel));
   
   // 动态添加eat方法
   // if ([NSStringFromSelector(sel) isEqualToString:@"eat"]) {
       
   
//}
  if (sel == @selector(eat:)) {
       
       
/*
         cls:
给哪个类添加方法
         SEL:
添加方法的方法编号是什么
         IMP:
方法实现,函数入口,函数名
         types:
方法类型
         */

       
// @:对象:SEL
        class_addMethod(
self, sel, (IMP)aaaa,"v@:@");
       
       
       
// 处理完
       
return YES;
 }
  return [superresolveInstanceMethod:sel];
}





Runtime 分类添加属性
例:给NSObject添加name属性

 NSObject*objc = [[NSObjectalloc] init];
    objc.
name= @"123";
    NSLog(@"%@",objc.name);



@interfaceNSObject (Objc)

@property(nonatomic,strong)NSString*name;

@end

#import"NSObject+Objc.h"

#import<objc/message.h>

@implementationNSObject (Objc)

//static NSString *_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");
}

@end
0 0
原创粉丝点击