RunTime

作者: 二先生Developer | 来源:发表于2018-02-23 23:16 被阅读9次
    1.使用消息发送机制创建对象,给对象发送消息
    导入 #import <objc/message.h>
      /* - OC
        Person * person = [Person new];
        [person run];
         */
        Person * person = objc_msgSend(objc_getClass("Person"), sel_registerName("alloc"));
        objc_msgSend(person, sel_registerName("init"));
        objc_msgSend(person, @selector(run));//需要在Build setting里面设置 输入msg修改为NO不检测调用方法是用运行时,苹果不建议直接使用objc_message来发送消息
    
    2. runTime方法交换的使用
    #import "NSURL+NewRequestUrl.h" //URL分类
    #import <objc/runtime.h>
    
    @implementation NSURL (NewRequestUrl)
    //当项目所有.m文件装载到内存优先执行load里面的指令,所以app启动之前就已经执行了load
    +(void) load{
       
    //    Method instanceMethod = class_getInstanceMethod([<#Class  _Nullable __unsafe_unretained cls#>], <#SEL  _Nonnull name#>)//对象方法
       
       Method classSystemMethod = class_getClassMethod(self, @selector(URLWithString:));
       Method classCustomMethod = class_getClassMethod(self, @selector(AwNewReqestUrlWithString:));
       method_exchangeImplementations(classCustomMethod, classSystemMethod);
    }
    
    +(instancetype) AwNewReqestUrlWithString:(NSString *) urlSting{
       
       NSURL * url = [NSURL AwNewReqestUrlWithString:urlSting];
       if ([url isKindOfClass:[NSNull class]] || url == nil || url.description.length == 0) {
           NSLog(@"url为nil");
       }
       return url;
    }
    @end
    
    //app已经入这个控制器,调用URLWithString方法时,就交换,最大的好处如果原工程相同方法比较多,又需要修改,可以不改变原工程的这些方法法,新增一个方法,避免去过多修改别人代码导致混乱,直接修改全局,减少工作量!
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        /**
         oc: 方法实质上就是 Sel指针指向 ---> IMP指针  --->IMP指向具体的方法实现代码
         */
        NSURL * url = [NSURL URLWithString:@"http://www.baidu.com百度"];
        NSURLRequest * request = [NSURLRequest requestWithURL:url];
        NSLog(@"%@",request);
        
    }
    
    3. KVO本质其实也是runtime
    #import "ViewController.h"
    #import "Person.h"
    @interface ViewController ()
    
    @end
    
    @implementation ViewController{
        Person * p;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //KVO 底层原理也是应用运行时
        p  =[[Person alloc] init];
        //1.动态创建Person子类(NSKVONotyfing_person)2.改变p对象的类型为(NSKVONotyfing_person)
        [p addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
    }
    //KVO是对象属性的setter方法监听,所以对 对象的成员属性的监听是不会走 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context方法
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
        NSLog(@"%@---%@---%@",keyPath,object,change);
    }
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        p.name = @"awuge";
    }
    
    // 切记切记:在使用了键值观察者模式一定要在移除,不然会发生崩溃
    -(void)dealloc{
        [p removeObserver:self forKeyPath:@"name"];
    }
    
    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    @property(nonatomic,strong) NSString * name;
    @end
    -------------------
    
    #import "Person.h"
    
    @implementation Person
    
    @end
    
    
    
    #import "Person.h"
    
    @interface NSKVONotyfing_person : Person
    
    @end
    
    -----------------------------------
    
    #import "NSKVONotyfing_person.h"
    
    @implementation NSKVONotyfing_person
    
    -(void)setName:(NSString *)name{
        //willChangeValueForKey和didChangeValueForKey调用根据添加观察者时设置的NSKeyValueObservingOptionNew(改变以后在调用)值 NSKeyValueObservingOptionOld(改变之前调用)
        [self willChangeValueForKey:name]; 
        [super setName:name];
        [self didChangeValueForKey:name];
    }
    @end
    
    屏幕快照 2018-03-08 下午3.37.52.png

    相关文章

      网友评论

          本文标题:RunTime

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