苹果官网上对OC的描述是:Objective-C是一门非常动态的语言(Objective-C is a very dynamic language)。OC的动态特性可从三方面描述
- 动态类型识别(Dynamic typing):最终判定该类的实例类型是在运行期间
- 动态绑定(Dynamic binding):在运行时确定调用的方法
- 动态加载(Dynamic loading):在运行期间可添加模块(类、方法)
- 理解动态类型识别
- OC中有一个可以表示任何实例对象类型的关键字--id,将对象声明为id类型,可根据需要,赋予不同类型的实例对象。
- 父类指针同样也可以指向子类实例对象,编译期指针类型为父类,运行后可判断为具体的某个子类。
- 这段代码也可以很好的解释OC的动态类型识别:NSData *test = [[NSString alloc] init]; 在编译期test被认为NSData类型,运行后则为NSString类型,其值为空字符串("")。
- 理解动态绑定
关于动态绑定,苹果官网的给的解释为:(determining the method to invoke at runtime)。我理解为运行时决定调用方法(更专业的应该叫消息发送,大家不要纠结这细节哈)。动态绑定是实现OC多态的基础,所谓多态指的是不同对象对同一方法(叫函数也行)有着不同实现,常见于子类继承父类,重写父类方法,不同的子类实现该方法不同(见动态类型识别解释第二条),通过父类指针指向子类来完成。
- 理解动态加载
- 动态添加属性:我们都知道,在分类(category)中添加属性,只会生成setter和getter,不会生成变量,如果想实现添加变量这个需求,需要使用对象关联。objc_getAssociatedObject()和objc_setAssociateObject(),关于这两个方法的使用,网上一搜一大堆,在这里就不赘述了。相关联就使用到了OC的动态特性。
- 动态添加方法:通过
class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, const char * _Nullable types)
各个参数解释:cls 类名;name SEL类型的方法名(通过@selector()得到);imp,函数指针,如果是C方法的话可直接写方法名,如果是OC方法的话,可通过class_getMethodImplementation(Class cls, SEL name)方法获得;types,返回值类型,是个C字符串,"V@:"表示返回值类型为空,无参,"i@:"返回值为int,无参,"i@:@",返回值为int,一个参数。 - 动态添加类
通过
objc_allocateClassPair(Class _Nullable superclass, const char * _Nonnull name,size_t extraBytes)
添加要动态创建的类,然后添加方法和变量,最终将创建的类注册到runtime中
objc_registerClassPair(Class _Nonnull cls)
上边就是对OC这门动态语言的理解了,面试的时候被问到过这个问题,但一紧张,说的那叫一个乱七八糟啊。虽然表达的也是这个意思,但说的很没有条理,想到哪说到哪。抽空整理一下,也理一下脑袋中的思路。有错勿喷,欢迎指正。