为什么说Objective-C是一门动态的语言?

823 阅读5分钟

有动态语言一般都有一个静态语言来对应,那理解的切入口就从静态语言开始把。

静态语言也被称为强类型语言,即编译时变量的数据类型就可以确定。例:Java、C、C++

编译:就是把高级语言编程计算机可以识别的2进制语言。编译期只是做了一些翻译功能,并没有吧代码放到内存中运行起来,而只是把代码当成文本进行操作,如检查错误。

编译期分类内存并不是说在编译期就把程序所需要的空间在内存中分配好,而是说在编译期生成的代码中产生一些指令,在运行代码时通过这些指令把程序所需的内存分配好。只不过在编译期的时候就知道分配的内存大小,并且知道这些内存的位置。

强类型语言:是一种总是强制类型定义的语言,要求变量的使用要严格符合定义,所以变量都必须先定义后使用。一旦一个变量被指定了某个数据类型,如果不经过强制类型转换,那么该变量永远是这种数据类型。一个变量的类型是声明的时候就已经确定了,因此更安全。

从上的定义中可以理解出静态语言基本上在编译期间不会做很大的操作,只是处理一些运行期需要的东西且在编译时就确定了类型。动态语言也被称为弱类型语言,是指在运行时才确定数据类型的语言,变量在使用之前无需声明类型,通常变量的值是被赋值的那个值的类型。例:PHP、JavaScript、Python

运行期:是把编译后的文件交给计算机执行,直到程序运行结束。所谓运行期就是把磁盘中的代码放到内存中执行起来。类加载时运行期的开始部分。

弱类型语言:强类型是强制类型而弱类型是可以忽略数据类型的语言。一个变量可以赋值不同数据类型的值,一个变量的类型是由其上下文决定的,强类型因为早早确定了类型而更安全,因此弱类型相对而言更不安全,但因为其类型有上下文决定因而效率更高。

理解了相关定义再来说说Objective-C。Objective-C是C语言的严格超集--任何C语言程序不经修改就可以直接通过Objective-C编译器编译。因此Objective-C拥有C的基本特性,但问题来了C语言从语言类型上是属于静态语言(强类型语言),为什么Objective-C却被称为是一门动态语言呢?

Objective-C被称为动太语言主要体现在其相对于C语言拥有动态性动态性又主要体现在动态类型动态绑定动态加载

动态类型:

指对象指针类型的动态性,具体是指使用id类型将对象的类型推迟到运行时才确定,由赋值给它的对象类型决定对象指针的类型。

id:是公用的对象类型,可以用来存放任何类的对象

而上面提到静态语言的数据类型在编译时就已经确定了。然而在OC中其他指明类型的都为静态类型且跟静态语言一样在编译时就已经确定了类型。

那么为什么要引入动态类型呢?在缺少泛型的静态语言类型中实现容器类时,需要写一种针对通用类型对象的容器类,然后再通用类型和实际类型中不停的强制类型转换。无论如何类型转换会破坏静态类型。而对于动态类型语言则完全没有类型转换这一问题。既然要确定该对象的具体类型也可以通过NSObject中的isKindOfClass方法来动态判断对象的类型。

向动态类型发送任何消息,无论该对象实体的公开接口中有没有对应的反方法,编译器也仅会发出警告,并不会崩溃。也就因为使用动态类型不会报错,万一程序程序的后期崩溃正好在动态类型上,那问题点还是很难发现的。

动态加载

主要表现在资源的动态加载代码模块的加载。这些资源在运行时根据需要有选择地加入到程序中。可以降低内存的开销,提高整个程序的性能,也提高了扩展性。

动态绑定

运行时确定要调用的方法。动态绑定将要调用的方法的确定也推迟到运行时。编译时方法的调用并不和代码绑定一起,只有在消息发送出来之后,才确定被调用的代码。直观点的意思就是在运行时才判断需要调用什么方法。当向一个动态类型确定的对象发送消息时,运行时环境系统会通过接收者的isa指针定对象的类,并以此为起点确定被调用的方法,方法和消息时动态绑定的。

因为动态绑定是在运行时通过动态类型来实现,所以动态绑定是建立在动态类型的物质基础之上的,在运行时对象的类型确定后,对象的属性和方法也就确定了,包括类中原来的属性和方法,已经运行时动态新加入的属性和方法。

其实从动态性的三大表现中不能发现,基本实现都是基于运行时这一特性,既然说了这么多那必然要了解下运行时的特性。