zoukankan      html  css  js  c++  java
  • IOS

    runtime 消息机制

    runtime 可以为类动态添加方法,属性,监听类的属性改变

    一.下面 演示动态为分类添加属性

    // 定义一个person类
    
    Person.h
    
    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    
    @property (nonatomic, copy)NSString * name;
    
    @end

    为Person添加分类

    #import "Person.h"
    
    @interface Person (hobby)
    
    //分类中能够定义属性,但是没有自动生成getter&setter方法,对应的成员变量也不生成
    @property(nonatomic,copy) NSString *hobby;
    
    //- (NSString *)hobby;
    //- (void)setHobby:(NSString *)hobby;
    @end
    #import "Person+hobby.h"
    #import <objc/runtime.h>
    
    const char * KEY = "hobby";
    @implementation Person (hobby)
    - (NSString *)hobby{
        /*
         1.要求关联的对象
         2.关联的key
         */
        return objc_getAssociatedObject(self, KEY);
    }
    
    - (void)setHobby:(NSString *)hobby{
        /*
         关联对象
         1. 要求关联的对象
         2. 关联的key
         3. 关联的值
         4. 关联策略- 属性关键字
         */
        
        objc_setAssociatedObject(self, KEY, hobby, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    @end

    在主程序中调用

     // MARK: - 在分类中添加的 hobby 属性
        Person * p = [[Person alloc] init];
        
        self.p = p;
        
        p.name = @"张三";
        
        [p setHobby:@"打篮球"];
        
        //在分类中动态添加属性
        NSLog(@"姓名:%@,爱好:%@",p.name,p.hobby);

    打印结果

    2016-08-06 23:20:58.655 runtimeDemo[2879:382062] 姓名:张三,爱好:打篮球
    

     属性 其实就是get/set 方法。我们可以使用  objc_setAssociatedObject/objc_getAssociatedObject  实现 动态向类中添加 方法

    二.监听属性的值的改变

     // MARK: - 监听对象属性的改变
        
        NSLog(@"isa:%@",[p valueForKeyPath:@"isa"]);
        
        [p  addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:NULL];
       
        NSLog(@"isa:%@",[p valueForKeyPath:@"isa"]);
        
        p.name = @"李四";

    打印信息

    2016-08-06 23:20:58.656 runtimeDemo[2879:382062] isa:Person
    2016-08-06 23:20:58.656 runtimeDemo[2879:382062] isa:NSKVONotifying_Person

    KVO 的原理就是 为p类添加监听的时候 ,重新生成了一个类,这个类继承p,重写了p属性的setter方法

    代码在Github上面:https://github.com/Amuxiaomu/runtimeDemo

  • 相关阅读:
    python_Opencv_使用Matplotlib模块
    django中同源策略和跨域解决方案
    ES6常用语法
    django之页面缓存
    django组件之ContentType
    我的博客园设置
    rest_framework 之版本控制
    rest_framework 之分页器
    在django项目中手动模拟实现settings的配置
    rest_framework之url控制器详解
  • 原文地址:https://www.cnblogs.com/DreamLinku/p/5745193.html
Copyright © 2011-2022 走看看