运行时runtime

2 篇文章 0 订阅
  • 运行时是苹果提供的比较底层的C语言API(C语言库)
  • 利用运行时可以:
    • 可以获得对象中的所有成员变量,成员属性,成员方法
    • 以及其它很牛逼的功能。这里暂且只介绍上一点。

需求背景

  • 需求:更改UITextField里占位文字的颜色,而我们不知道怎么改,猜测它有个label用来显示占位文字,但头文件里没有暴露,我们要怎么证明它有这个成员变量并且拿到它呢?

具体使用

  • 导入头文件<objc/runtime.h>
  • 用到下面这个方法:Ivar的意思是instance varlables(成员变量)。给它一个类,他会把这个类里面的所有成员变量返回给你。其中第一个参数是要传一个类,第二个参数要传个unsigned int类型的数据,用来告诉你有多少个成员变量。注意它有个星号*,要传指针指向的内存地址,要加个&。传入指针指向的地址,它才能改掉地址里的内容。
class_copyIvarList(<#__unsafe_unretained Class cls#>, <#unsigned int *outCount#>)
  • 那么我们传入参数,并且接受这个方法的返回值
    unsigned int count = 0;
    Ivar *ivars = class_copyIvarList([UITextField class], &count);
  • Ivar上面说过了,就是成员变量。UITextField这个类里面有多个成员变量,是个数组,指针会指向数组中的第一个元素(C语言知识)
  • 然后取出这个元素:*ivars就是指针指向的地址的内容,注意区别于上面Ivar *ivars是定义了一个指针,实际意思是(Ivar *)ivars(又是C语言的知识)。通过ivar_getName(Ivar v)方法可以拿到名称,打印。
Ivar firstIvar = *ivars;
NSLog(@"%s",ivar_getName(firstIvar));
  • 然后查看第二个元素:指针指向数组,只要让指针+1就可以看第二个元素了
    Ivar secondIvar = *(ivars + 1);
    NSLog(@"%s",ivar_getName(secondIvar));
  • 要想查看全部元素,那么就for循环
    for (int i = 0; i < count; i++) {
        Ivar ivar = *(ivars + i);
//也可以这么写,因为数组名就是首元素的地址,而指针名(就是指针指向的地址)就是首元素的地址,那么指针名就等同于数组名,所以指针名就可以当做数组来用
        // Ivar ivar = ivars[i];
        NSLog(@"%s",ivar_getName(ivar));
    }
  • 最后,这个类不归ARC管理,上面有copy了记得释放free(ivars);

回到需求背景

  • 用运行时可以看到UITextfield里确实有个_placeholderLabel成员变量,而且是在.m文件里定义的(带下划线的),没有直接暴露在外面给我们拿到。
  • 直接没法拿到,那么可以通过KVC来拿到
UILabel *placeholderLabel = [self valueForKeyPath:@"_placeholderLabel"];
// 小知识点:keyPath里传placeholderLabel(不带下划线)也是可以的,它找不到placeholderLabel胡i去找有没有下划线的成员变量
  • 然后对着placeholderLabel想怎么设置就怎么设置
placeholderLabel.textColor = [UIColor redColor];
  • 还可以更精简:
[self setValue:[UIColor redColor] forKeyPath:@"placeholderLabel.textColor"];

其它运行时的方法

  • 找出类的所有成员属性
    unsigned int count = 0;
    objc_property_t *propertys = class_copyPropertyList([UITextField class], &count);
    for (int i = 0; i < count; i++) {
        objc_property_t property = propertys[i];
        NSLog(@"%s",property_getName(property));
    }
    free(propertys);
  • 小知识点:用@property生成的成员属性和会自动生成一个带下划线的成员变量,所以有成员属性一定有成员变量,而有成员变量不一定有成员属性,因为可以自己定义下划线的成员变量而不是通过定义成员属性来定义。
  • 还有找出类里面的方法
Method *methods = class_copyMethodList(<#__unsafe_unretained Class cls#>, <#unsigned int *outCount#>)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值