zoukankan      html  css  js  c++  java
  • Dynamicaly Typed(动态定型), Objective-C Runtime Programming

      Objective-C跟C最大的差别,应该是动态定型(dynamicaly typed),支持在运行时动态类型决议(dynamic typing),动态绑定(dynamic binding)以及动态装载(dynamic loading)。Objective-C 在运行时可以允许根据字符串名字来访问方法和类,还可以动态连接和添加类,而C语言编译时静态绑定,甚至很多时候你没定义的方法直接就编译不过。

    Message

      Messaging是Object-C动态定型的实现方法。当调用一个类方法时,系统就给这个对象发消息:

      objc_msgSend(receiver, selector, arg1, arg2, ...)
    id target = getTheReceiver(); SEL method = getTheMethod(); if ( target == self || method == _cmd )[target performSelector:method];

     receiver指定哪个对象接收消息,selector是调用方法,arg1..后面是参数。

     所以每个类有两个必须的基本元素:

     1.A pointer to the superclass.(指向superclass的指针)

       2.A class dispatch table. (一张自己所支持方法的分发表)

      当它收到一个消息时message,它取出selector,然后遍历自己的dispatch table,如果在dispatch table,就去执行,否则把message传递给super。

    Message Forwarding

    既然Object-C是动态绑定,当它运行时,收到一个不支持的消息,那必定会出现异常,不特殊处理这个异常的话,程序就崩溃了。不过幸运的是,系统可以在error出现之前,通过判断对象是不是能调用这个方法:(negotiate代表你需要执行的函数)

    - negotiate {
        if ( [someOtherObject respondsTo:@selector(negotiate)] )
            return [someOtherObject negotiate];
    }

    不过这种方法就很笨重了,每一个方法就写一个函数,甚至很多时候你都不知道你需要支持什么函数,所以应该用如下方法来处理未支持的消息:

    - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
    {
        if ([self respondsToSelector:aSelector]) {
            return [super methodSignatureForSelector:aSelector];
        }
        else {
      //不支持的方法随便返回一个NSMethodSignature,当然不能返回nil,否则还是会崩溃
            return [NSMethodSignature signatureWithObjCTypes:"v@:"];
        }
    }
    
    -(void)forwardInvocation:(NSInvocation *)anInvocation
    {
        if ([self respondsToSelector:
             [anInvocation selector]])
            [anInvocation invokeWithTarget:self];
        else{
            //什么做,就不崩溃了
        }
    }

    这两个方法可以从NSobject继承重写,从anInvocation取出selector,如果是支持的就激活invoke,否则就不管了。通过重写这两个函数,即使这个类调用了不支持的方法,也不会导致程序崩溃了。

    既然这个方法可以防止系统崩溃,为什么系统不直接实现呢?估计还是效率问题,如果接收每个message都去判断是不是支持,那必定会耗费时间。

    Surrogate Objects 

    这里就简单说说surrogate。代理,顾名思义,也就是可以把对象接受到的消息转给一个代理object处理。也是通过重写上面说的两个函数:

    //surrogateObject1和surrogateObject2就是self的两个对象,用来作为self的代理,把self收到的消息转给surrogateObject1或2处理
    
    - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {  
    //对不同的aSelector,是返回self,还是返回surrogateObject1或surrogateObject2的NSMethodSignature就可
    }  
       
    - (void)forwardInvocation:(NSInvocation *)invocation {  
      //同理,对不同的selector,激活self或者是surrogateObject1或surrogateObject2
    }  

    一般没怎么用。大家可以自己看看。

     

    一般来说,了解编程语言的特征,对编写程序还是很有必要的。仅供参考。

    参考资料:ObjCRuntimeGuide.pdf(iOS官方文档)

      

  • 相关阅读:
    winform中的 listview的使用的讲解。
    快乐的一天从AC开始 | 20210716 | P1345
    快乐的一天从AC开始 | 20210715 | P4643
    快乐的一天从AC开始 | 20210714 | P3594
    快乐的一天从AC开始 | 20210713 | P3557
    快乐的一天从AC开始 | 20210712 | P2251
    P7294-[USACO21JAN]Minimum Cost Paths P【单调栈】
    AT4353-[ARC101D]Robots and Exits【LIS】
    2021牛客暑期多校训练营9C-Cells【LGV引理,范德蒙德行列式】
    Loj#2880-「JOISC 2014 Day3」稻草人【CDQ分治,单调栈,二分】
  • 原文地址:https://www.cnblogs.com/vicstudio/p/3283936.html
Copyright © 2011-2022 走看看