当前位置: 移动技术网 > IT编程>移动开发>IOS > 【Objective-C】Objective-C语言的动态性

【Objective-C】Objective-C语言的动态性

2019年06月20日  | 移动技术网IT编程  | 我要评论

林文正姿笔创始人阿华,17寸笔记本桌面壁纸,回南天持续多久

  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的相关内容之前在一篇博客中已经写过:

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网