美文网首页iOS Developer
Ios runtime学习 runtime应用场景举例

Ios runtime学习 runtime应用场景举例

作者: 1剑天下 | 来源:发表于2016-12-21 12:11 被阅读134次

    Runtime存在OC中的意义:

    Objc是一门动态语言,它会把一些决定性的工作推迟到运行时,这就需要一个运行时系统来执行编译后的代码。runtime是Object的核心。

    运行时最总要的四个应用场景

    1  关联对象  最多给分类动态添加属性,oc分类默认不能添加属性,运行时能够更好的的解藕,简化调用方的使用
    2  动态获取类的属性 用于字典转模型   
    3 交叉方法 黑魔法 对系统方法不满意自己写一个方法替换系统方法(不要轻易使用)对版本的依赖性很强 ,有可能现在能是,过一段时间就不能使用(AFN使用较多 ) 
        达到的目的:(1)拦截系统方法 (2)最好是拦截完系统方法后再实现自己的需求后再次回到系统方法中
    4  NSClassFromString 等(部分人认为)
    

    可以参考文档http://www.cocoachina.com/industry/20140527/8570.html

    下面列举运行时字典转模型的列子

    1. 创建一个模型
    #import <Foundation/Foundation.h>
    @interface Person : NSObject
    @property(strong, nonatomic) NSString * name;
    @property(strong, nonatomic) NSString * age;
    @property(strong,nonatomic) NSString * height;
    @property(strong,nonatomic) NSString * title;
    @property(strong,nonatomic) NSArray * friends;
    @end 
    
    #import "Person.h"
    @implementation Person
    // 作用 使模型能通过NLog打印出属性值
    -(NSString*)description
    {
        NSArray *key = @[@"name",@"age",@"height",@"title"];
        return [self dictionaryWithValuesForKeys:key].description;
      
    }
    @end
    

    2.创建Person的分类

    #import "Person.h"
    
    @interface Person (Runtime)
    /*
    给定一个数组 创建self对象
    */
    +(instancetype)YL_ObjectDic:(NSDictionary *)dict;
    /*
    获取属性列表
    
    返回 属性数组
    */
    +(NSArray*)YL_ObjectProperties;
    @end
    
    #import "Person+Runtime.h"
    #import <objc/runtime.h>
    @implementation Person (Runtime)
    
    //所有字典转模型框架的核心
    +(instancetype)YL_ObjectDic:(NSDictionary *)dict
    {
        id object =[[self alloc] init];
        
        // 获取类所有的属性
        
        NSArray *prolist =[self  YL_ObjectProperties];
        
        //遍历字典给每一个属性赋值
        [dict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            
            // 属性中存在这个key
            if ([prolist containsObject:key]) {
                
                // kvc 添加到字典
                [object setValue:obj forKey:key];
            }
        }];
        
        return object;
    }
    +(NSArray*)YL_ObjectProperties
    {
        //  运行时取得类的属性数组
        
        //Ivar: 成员变量
        //method:成员变量
        //propretty:属性
        //protocal:协议
        
        /*
         参数
         1.要获取的类
         2.类属性的个数指针
         
         返回值:所有属性的数组  c语言中数组的名字就指向第一个元素的地址
         */
        
        
        NSMutableArray *returnarry =[[NSMutableArray alloc] init];
        
        unsigned int  count = 0;
        
        objc_property_t *prolist = class_copyPropertyList([self class], &count);
        
        
        NSLog(@"属性的count:%d",count);
        
        
        // 遍历所有数组 从数组中取得所有的属性
        
        for (int i=0; i<count; i++) {
            
            objc_property_t pro = prolist[i];
            
            // 转字符串
            const char * proname =  property_getName(pro);// 获取属性的名字
            
            NSString *proStr =[NSString stringWithCString:proname encoding:NSUTF8StringEncoding];
            
            const char * attributes = property_getAttributes(pro);//获取属性类型
            
            NSString *proAttributes = [NSString stringWithCString:attributes encoding:NSUTF8StringEncoding];
            
            // 字符串转对应的立刻调用函数
            /*
            SEL _selector = NSSelectorFromString(proAttributes);
            id retVal = [self performSelector:_selector];
             */
        
    
            
            
            // 添加数组
            [returnarry addObject:proStr];
        }
        
        // 注意 :c语言的_copy,teturn,creat 需要释放
        
        free(prolist);
        
        
        
        
        
        return returnarry;
    }
    @end
    

    3 字典转模型调用

    - (void)viewDidLoad {
        [super viewDidLoad];
      
    
        // 获取person类属性数组  => 拿到属性数组 目的为了后面通过kvc赋值
        
        NSArray *properties = [Person YL_ObjectProperties];
        
        NSLog(@"%@",properties);
        
        // 字典模型设置
        
        Person *mode = [Person YL_ObjectDic:@{@"name":@"张三",
                                              @"age":@"张三",
                                              @"height":@19,
                                              @"title":@"YL",
                                              @"friends":@[@"韩韩",@"军军",@"强强"]
                                              }];
        
        NSLog(@"mode:%@",mode);
        
        NSLog(@"Arr:%@",mode.friends);
    }
    
    

    交叉方法待续。。。。

    相关文章

      网友评论

        本文标题:Ios runtime学习 runtime应用场景举例

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