美文网首页iOS DeveloperiOS Development
用Runtime减少代码量(objc/runtime.h的学习)

用Runtime减少代码量(objc/runtime.h的学习)

作者: 箪食豆羹 | 来源:发表于2017-02-21 12:32 被阅读174次

分析

各看官请看 项目中有如下页面需要实现


应用截图

优雅的实现方式

当然,最优雅的方式当属用UITableView+Model实现了,其中,“提供服务人员信息”、“订单服务信息”、“订单基本信息”为headerView,其他的每一行“XXX:xxxxx”都是一个由model(Model)控制的cell,每个model中包含title和detail字段,配置好数据源、代理(Controller),具体的布局、样式逻辑就交给Cell(View)来控制就OK了。
使用这种思想的方法,有一篇文章写的很好,推荐一下写一个iOS复杂表单的正确姿势

逗逼版实现方式

从图中可见,UILabel的数量极多,而其中又有三种字体,分别为一级标题,二级标题和内容,其中有字号和字体粗细之分。
如果刚好碰巧,之前实现这个页面的程序员非常耐dou心bi,所有label都手动添加进去,这时候需求来了,要改Appearence。
如果手动设置字体,不仅重复代码多,而且不方便,more,需要改变字号、增加UILabel等的话,将会十分麻烦。于是这时候可以利用OC之Runtime之便利,实现功能代码以满足项目需求。

逗逼版补救步骤

主要思路

  • 利用Runtime,取得当前类的属性列表
  • 通过便利属性列表,获得title或detail的label属性名
  • 利用KVC,通过属性名取得当前对象中的UILabel实例
  • 各种setFontsetColor......

实现代码

    unsigned int count = 0;
    // 获得属性列表
    objc_property_t *propertyList =  class_copyPropertyList([self class], &count);
    for(int i=0; i<count; i++) {
        //取得属性名
        objc_property_t property = propertyList[i];
        const char* propertyName = property_getName(property);
        //分情况进行不同的操作,此处分为detailLbl和titleLbl
        if (strstr(propertyName, "Title")) {
            UILabel *label = [self valueForKey:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]];
            [label setFont:[UIFont systemFontOfSize:kZFFontSizeThirdlyTitle weight:UIFontWeightRegular]];
        } else if (strstr(propertyName, "Detail")) {
            UILabel *label = [self valueForKey:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]];
            [label setFont:[UIFont systemFontOfSize:kZFFontSizeThirdlyTitle weight:UIFontWeightLight]];
        }
    }
    // 释放资源
    free(propertyList);

总结

然而,本文这种方式来使用Runtime是一种非主流的方式,只在特定业务或者编程需求下使用,正确的Runtime应用,是在用于那些字典模型互相转、实现多继承、添加属性关联对象等功能上,关于Runtime更多详情可以看我的另一篇文章 Runtime学习笔记

相关文章

网友评论

    本文标题:用Runtime减少代码量(objc/runtime.h的学习)

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