iOS开发有很多很神奇的东西,虽然有时候用到的不是很多,或者说目前还没用到,但是作为一名iOS工程师,了解和掌握这些东西是必不可少的。下面就介绍一位重量级的选手--iOS的黑魔法----运行时机制。
何为运行时?下面两句话就是对其最基础也最准确的概括介绍:
运行时(Runtime):
* 苹果官方一套C语言库
* 能做很多底层操作(比如访问隐藏的一些成员变量\成员方法....)
其实作为一名开发工程师,已经开发了一年多了,用到运行时机制的情况也是屈指可数,但是觉得这个知识点依然还是很重要,面试的时候也是很受青睐的一个问题,下面先简单的介绍一下这个神奇的功能。目前对于运行时的探索分为两个方面:
一:利用运行时获得某些对象或者类的成员变量和属性
乍一看会觉得不就是获取一些成员变量和属性嘛,直接点进去头文件看一下不就行了嘛?至于牵涉到这么复杂的问题吗?请注意,这里说的的成员变量,更加准确的描述是一些私有的成员变量,这里就可以想象到它的价值了吧!没错,自定义控件!
利用运行时自定义控件的情景及用法:
自定义控件的情景自然无需赘述,那就是系统自带的控件难以满足我们的需求,所以要自定义控件。下面主要介绍一下用法,介绍用法通过一个例子来说明吧。开发过程中,有木有发现UITextField竟然没有暴露一个属性来设置起占位文字的颜色,对于一个这么常用的控件,这么常见得需求都没有暴露出来,真想不通啊。对于产品狗的这种需求,自然就得自定义UITextField了,实现起来思路有很多,但是最简单的一种就是这里要介绍的----运行时机制。我们可以通过运行时机制打印出来UITextField的成员变量,来看看有没有符合条件的,直接尝试对这个成员变量进行设置可谓一步到位,无需多余的其他复杂的想法。说干就干,
+ (void)getProperties
{
unsigned int count = 0;
objc_property_t *properties = class_copyPropertyList([UITextField class], &count);
for (int i = 0; i<count; i++) {
// 取出属性
objc_property_t property = properties[i];
// 打印属性名字
XMGLog(@"%s <----> %s", property_getName(property), property_getAttributes(property));
}
free(properties);
}
+ (void)getIvars
{
unsigned int count = 0;
// 拷贝出所有的成员变量列表
Ivar *ivars = class_copyIvarList([UITextField class], &count);
for (int i = 0; i<count; i++) {
// 取出成员变量
// Ivar ivar = *(ivars + i);
Ivar ivar = ivars[i];
// 打印成员变量名字
XMGLog(@"%s %s", ivar_getName(ivar), ivar_getTypeEncoding(ivar));
}
// 释放
free(ivars);
}<span style="color:#703daa;">
</span>
通过上面的运行时提供的一些方法,就可以轻松获得一些控件隐藏的成员变量和属性,通过上面的打印可以得到很多,稍微筛选一下就会看到一个很可疑的成员变量----
_placeholderLabel,没错,就是它,稍加验证就会发现,完全可行,那岂不是很轻松,直接通过KVC进行设置即可:
[selfsetValue:self.textColorforKeyPath:_placeholderLabel.textColor];
PS:KVC在开发中是很常用也很实用的一个方法,务必掌握,另外,它很常用的一种方法通过点语法进行递归设置。
轻松搞定,不用再考虑其他的太复杂的想法,简单明了!!!