浅谈 iOS 动态特性

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34417314/article/details/73477989


OC是一门动态类型语言
说动态类型之前,先说俩概念:编译、运行。

编译:编译简单来讲就是把自己写的源代码翻译成机器能识别的语言。可以认为是编译器检查语法、识别静态类型数据等过程,是不会将代码运行到内存中去的,也就是说编译时是没有内存分配的

运行:就是将代码加载到内存中去,并在内存中做一些操作和判断等。

OC的动态特性体现在三个方面:
动态类型、动态绑定、动态加载
1.1 动态类型
      简单来讲,动态类型就是id类型,它区别于静态类型(如int类型、NSString等基本类型,在编译阶段会被识别,静态类型可以提高程序的可读性),这些id类型只有在运行的时候(runtime)才会根据语境来识别,编译时不会被识别。
比如:一个id类型的对象,若我们不确定其类型,则通常会用 isKindOfClass方法去判断,然后对响应处理
// 不确定obj类型
id obj = name;   
// 做判断,若obj为NSString类型
if ([obj isKindOfClass:[NSString class]]) {
// 做相应处理
NSString * str = (NSString *)name;
}
上面的isKindOfClass就是通常用的一种动态类型识别的一个函数,其他还有诸如
-(BOOL)isMemberOfClass:classObj是否是classObj的实例
-(BOOL)respondsTosSelector:selector  类中是否有这个方法
NSClassFromString(NSString*);由字符串得到类对象
NSStringFromClass([类名 Class]);由类名得到字符串
Class rectClass= [Rectangle class];通过类名得到类对象
Class aClass =[anObject class];通过实例得到类对象
if([obj1 class]== [obj2 class])判断是不是相同类的实例
等常见动态类型识别方法
补充:
类对象
*类对象再程序运行时一直存在。
*类对象是一种数据结构,存储类的基本信息:类大小,类名称,类的版本以及消息与函数的映射表等
*类对象所保存的信息在程序编译时确定,在程序启动时加载到内存中。
*类对象代表类,class代表类对象,类方法属于类对象
*如果消息的接收者是类名,则类名代表类对象
*运行时,所有类的实例都由类对象生成,类对象会把实例的isa的值修改成自己的地址,每个实例的isa都指向该实例的类对象
*从类对象里可以知道父类信息、可以响应的方法等
*类对象只能使用类方法,不能用实例方法

任意NSObject的子类都会继承NSObject的isa实例变量,isa是一个指针,当NSObject的子类实例化对象时,isa 实例变量永远是对象的第一个实例变量。运行时,所有类的实例对象都由类对象产生,类对象会把实例对象的 isa 指针修改成自己的地址,每个实例对象的 isa 指针都指向该实例的类对象,从类对象中可以获取父类信息,可响应的方法等

多态:不同的对象以自己的方式响应相同的消息。

1.2动态绑定
     一个对象何时调用指定的方法不是在编译时决定,而是在运行时决定的。
     OC中,对象调用函数称为消息发送。[obj  msgSend];  obj为消息的接受者,msgSend为消息名
消息函数的作用如下:
首先动态确定消息接受者 (obj) 的类型,找到接受者的 isa 指针,然后在 isa 指针指向的 Class 对象中使用第二个参数 selector 查找方法;
如果没找到,就使用当前class中的新的 isa 指针到上一级父类对象中查找
找到方法后,再根据obj中的 self 指针找到当前的对象,调用当前对象的具体实现的方法(IMP)。然后传参,调用实现方法
若一直找到NSObject的class对象仍未找到所调用的方法,就会报不能识别发送消息的错误 
    Unrecognized selector send to instance xxx...



1.3动态加载
举个例子,开发的时候icon图片的时候在Retina设备上要多添加一个张@2x的图片,当设备更换的时候,图片也会自动的替换。
再有就是例如运行时加载新类,以及方法的动态加载等,这两个我尚未深入研究,有时间再细看。

本文参考自:

http://blog.csdn.net/tskyfree/article/details/7984887




展开阅读全文

没有更多推荐了,返回首页