zoukankan      html  css  js  c++  java
  • 【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

     

  • 相关阅读:
    Leetcode 538. Convert BST to Greater Tree
    Leetcode 530. Minimum Absolute Difference in BST
    Leetcode 501. Find Mode in Binary Search Tree
    Leetcode 437. Path Sum III
    Leetcode 404. Sum of Left Leaves
    Leetcode 257. Binary Tree Paths
    Leetcode 235. Lowest Common Ancestor of a Binary Search Tree
    Leetcode 226. Invert Binary Tree
    Leetcode 112. Path Sum
    Leetcode 111. Minimum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/xjf125/p/11050068.html
Copyright © 2011-2022 走看看