【Objective-C】Objective-C语言的动态性
Objective-C语言的动态性主要体现在以下3个方面
(1)动态类型:运行时确定对象的类型。
(2)动态绑定:运行时确定对象的方法。
(3)动态加载:运行时加载需要的资源或者或代码模块。
一、动态类型
动态类型指对象指针类型的动态性,具体地说就是使用id类型将对象的类型推迟到运行时才确定,由赋给它的对象类型决定该对象类型(说起来怎么这么绕口),也就是说id修饰的对象是动态类型对象,其他在编译期指明类型的为静态类型对象,所以开发中如果不是涉及到多态,尽量还是使用静态的类型,这样编写错误,编译器会提前查出问题,可读性更高一点。
//编译时认为是NSString,这是赋值了一个NSData对象编译器会给出警告信息:Incompatible pointer types initializing 'NSString *' with an expression of type 'NSData *'
NSString *testObject = [[NSData alloc]init];
//编译其认为是NSString,所以允许使用NSString的方法,不会有警告和错误,
[testObject stringByAppendingString:@"string"];
//编译期不允许使用NSData的方法,错误提示;No visible @interface for 'NSString' declares the selector 'base64EncodedDataWithOptions:'
[testObject base64EncodedDataWithOptions:NSDataBase64Encoding64CharacterLineLength];
如以上代码,testObject在编译时,指针的类型是NSString,也就是说编译时期是被当做一个NSString类型来处理,编译器在类型检查时发现类型不匹配会给出警告信息,testObject在运行时,指针指向的是一个NSData对象,因此如果指针调用了NSString的方法,那么虽然编译通过了,但运行时会出现崩溃,
二、动态绑定
动态绑定是建立在动态类型的基础之上,在OC的消息分发机制下将要执行的方法推迟到运行时才确定,可以动态的添加方法。也就是说一个OC对象是否调用某个方法不是在编译器确定的,方法的调用不和代码绑定在一起,而是到了运行时根据发出的具体消息,才去动态的确定需要调用的代码。
三、动态加载
动态加载分为两部分:动态资源的加载(如:图片资源),代码模块的加载;这些都是在运行时根据需要有选择性的添加到程序中的,是一种代码和资源的“懒加载”模式,这样降低编译时期对内存的开销,提供程序的性能。
如:资源在动态加载图片进行屏幕适配时,因为同一个图片对象可能会准备几种不同分辨率的图片资源,程序就会根据当前机型动态的选择对应分辨率的图片,如:@1x,@2x,@3x的。
四、消息传递机制
在OC中,方法的调用不能再去理解为对象调用其方法,而是要理解成对象接收消息。消息的发送采用“动态绑定”的机制,具体会调用那个方法直到运行时才确定。方法的调用其实就是告诉对象要做些什么事,给对象发送一个消息,对象为就是接收者recevier,调用的方法及其参数就是消息message,如果要给一个对象传递消息,可以表示为:[receiver message:xxx]。
在消息传递机制中,当开发者编写[receiver message:xxx]语句进行发送消息后,编译器都会将其转换成objc_msgSend C语言的发送格式。格式为:
void objc_msgSend(id self, SEL sel ...);
这个函数参数可变,第一个参数填入消息的接收者,第二个参数传入的是消息,后面可以跟一下可选的消息参数。有了这些参数,objc_msgSend就能根据接收者的isa指针,到其对象的方法列表中以sel 的名称寻找对应的方法。若找到对应的方法,就会转到它的实现代码执行,如果找不到,就去父类中寻找,如果找到了根类还是无法找到对应的方法,说明接收者对象无法响应该消息,那么就会触发消息转发机制,给开发者一次补救程序的机会。
五、消息转发机制
如果在消息传递过程中,接收者无法响应收到的消息,那么就会触发到消息转发机制。
消息转发提供了3道防线,任何一个起了作用,都能补救此次消息转发。依次为:
(1)动态的补加方法的实现
+(BOOL)resolveClassMethod:(SEL)sel
+(BOOL)resolveInstanceMethod:(SEL)
(2)直接返回消息到转发到的对象(就是将消息发送到另一个对象去处理)
-(id)forwardingTargetForSelector:(SEL)aSelector
(3)手动生成签名并转发给另外一个对象
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
-(void)forwardInvocation:(NSInvocation *)anInvocation
六、OC的编译时和运行时都做了哪些工作?
编译时:该阶段,编译器对语言进行编译,编译器只会对语言进行最基本的检查报错、语法分析等,并将程序代码翻译成计算机能够识别的语言。那编译通过了,是不是就可以成功执行呢?你太单纯了,想的美。
运行时:程序通过了编译之后,就会将编译好的代码转载到内存中,这时候就会对类型进行检查,不仅仅是简单的扫描分析,此时若出现问题,程序可就Game Over了。
编译时就是一个静态的阶段,类型明显错误,就会被直接检查出来,运行时时动态的阶段,会将程序与开发环境结合起来。
OC是动态运行时语言,主要指的是OC语言的动态性。
动态性即OC的动态类型、动态绑定、动态加载,将对象类型的确定、方法调用的确定、代码和资源的转载推迟到运行时记性,灵活方便。
Runtime的相关内容之前在一篇博客中已经写过:https://www.cnblogs.com/xjf125/p/10154488.html
【Objective-C】Objective-C语言的动态性的更多相关文章
- Objective-C与C++的区别
1.两者的最大相同:都是从C演化而来的面相对象语言,两者都兼容标准C语言 2.两者的最大不同:Objective-C提供了运行期动态绑定机制,而C++是编译静态绑定,并且通过嵌入类(多重继承)和虚函数 ...
- PHP、 Ruby、Python、Java、C++、C、Objective C——编程语言之禅
PHP是你豆蔻年华时的心上人,她是情窦初开的你今年夏天傻乎乎追求的目标.玩一玩可以,但千万不要投入过深,因为这个“女孩”有严重的问题. Ruby是脚本家族中一个非常漂亮的孩子.第一眼看她,你的心魄就会 ...
- 关于Objective C的私有函数
(1)很多从其他语言(例如C++)转到objective c的初学者,往往会问到一个问题,如何定义类的私有函数?这里的“私有函数”指的是,某个函数只能在类的内部使用,不能在类的外部,或者派生类内部使用 ...
- 《深入理解Java 7核心技术与最佳实践》读书笔记(2) Java语言动态性引言
Java语言是一种静态类型的编程语言.静态类型的含义是指在编译时进行类型检查.Java源代码中的每个变量的类型都要显式地进行声明.所有变量.方法的参数和方法返回值的类型在程序运行之前就必须是已知的.J ...
- Java 编程的动态性 第1 部分: 类和类装入--转载
原文地址:http://www.ibm.com/developerworks/cn/java/j-dyn0429/ 本文是这个新系列文章的第一篇,该系列文章将讨论我称之为 Java 编程的动态性的一系 ...
- C语言程序代写(Linux下线程)
联系QQ:928900200 CSCI 3120 Operating Systems Summer 2014 Handout 3Assignment 2Date Due: June 5, 2014 b ...
- Java学习笔记--脚本语言支持API
Java语言的动态性之脚本语言支持API 随着Java平台的流行,很多的脚本语言(scripting language)都可以运行在Java虚拟机啊上,其中比较流行的有JavaScript.JRuby ...
- Go 语言中的 Http 路由基础
最近在写一些 Go 语言的 Web 应用,因为 Go 语言中的 Web 应用和 Python 中的不太一样,具体的区别应该和语言的动态性是有所联系的,同时,也和语言的内置库支持有所联系,所以这就导致了 ...
- iOS书写高质量代码之耦合的处理
原创 2016-12-26 MrPeak MrPeak杂货铺 耦合是每个程序员都必须面对的话题,也是容易被忽视的存在,怎么处理耦合关系到我们最后的代码质量.今天Peak君和大家聊聊耦合这个基本功话题, ...
随机推荐
- 洛谷 题解 P5534 【【XR-3】等差数列】
我又双叒叕被包菜辣! 题目 这道题是不久前的考试题,现在来水一篇题解 扯回正题 题目很明显的告诉你了,这是一个等差数列, 然后,还告诉你了首项, 第二项, 项数. 你还想咋滴 告诉了你首项和第二项,相 ...
- luogu P1356 数列的整数性 |动态规划
题目描述 对于任意一个整数数列,我们可以在每两个整数中间任意放一个符号'+'或'-',这样就可以构成一个表达式,也就可以计算出表达式的值.比如,现在有一个整数数列:17,5,-2,-15,那么就可以构 ...
- 你真的了解JSON吗?
一.JSON——JavaScript Object Notation JSON 是一种语法用来序列化对象.数组.数值.字符串.布尔值和null .它基于 JavaScript 语法,但与之不同:一些J ...
- 2017 ACM/ICPC 沈阳 K题 Rabbits
Here N (N ≥ 3) rabbits are playing by the river. They are playing on a number line, each occupying a ...
- usb工业相机之硬件设计-双缓冲-双端口sdram-fpga
usb工业相机之硬件设计-双缓冲-双端口sdram-fpga 在前期的产品设计中,采用cb提供的结构,68013直接操作摄像头,iic配置摄像头寄存器,板载晶振提供时钟,摄像头的pclk直接接ifcl ...
- VMware虚拟机安装Linux(CentOS)系统
vmware workstation 虚拟机官方下载路径:https://www.vmware.com/cn/products/workstation-pro/workstation-pro-eval ...
- UWP 应用启动速度优化——关闭加载动画
准备 在开始之前,我们应该先处理好预启动来加速启动应用.请参见文末链接. 步骤 关闭加载动画主要在包清单文件中进行. 首先,以代码方式打开 Package.appxmanifest,在顶部的 Pack ...
- 【hibernate】映射可嵌入式组件
[hibernate]映射可嵌入式组件 转载:https://www.cnblogs.com/yangchongxing/p/10376452.html 可嵌入 Address 类,没有对应的数据表 ...
- ES6 promise 使用示例
new Promise(function (resolve, reject) { $.ajax({ type : 'post', data : formData, dataType : 'json', ...
- 《CSAPP》实验一:位操作
<CSAPP>号称程序员圣经,虽然中文译名为<深入理解计算机系统>,但其实没那么"深",只是覆盖面很广,一般用作计算机专业大一导论课的教科书.早就听闻书上配 ...