zoukankan      html  css  js  c++  java
  • [ios]伪继承,消息转载【转】

    http://www.cnblogs.com/fkdd/archive/2012/03/14/2396284.html

    1.伪继承

         尽管再objtive-C中不提供多继承,但它提供了另外一种解决方案,使对象可以响应在其它类中实现的消息(别的语言中,一般叫方法,两者无差别). 这种解决方案叫做消息转发,它可以使一个类响应另外一个类中实现的消息。

         在一般情况下,发送一个无法识别的消息会产生一个运行时的错误,导致应用程序崩溃,但是注意,在崩溃之前,iphone运行时对象为每个对象提供了第二次机会来处理消息。捕捉到一条消息后可以把它重定向到可以响应该消息的对象。

         这个功能完全通过消息转发来实现,发送消息给一个无法处理该选择器的对象时,这个选择器就会被转发给 forwardInvocation 方法.接收这条消息的对象,用一个NSInvocation的实例保存原始的选择器和被请求的参数.所以,我们可以覆盖 forwardInvocation 方法,并把消息转发给另外一个对象.

    1.1 实现消息转发功能

       在给程序添加消息转发功能以前,必须覆盖两个方法,即methodSignatureForSelector: 和 forwardInvocation:。methodSignatureForSelector:的作用在于为另一个类实现的消息创建一个有效的方法签 名。forwardInvocation:将选择器转发给一个真正实现了该消息的对象.

    例子:

    1.

    复制代码
    1 - (NSMethodSignature*)methodSignatureForSelector:(SEL)selector
    2 {
    3 NSMethodSignature* signature = [super methodSignatureForSelector:selector];
    4
    5 if (!signature)
    6 signature = [self.carInfo methodSignatureForSelector:selector];
    7
    8 return signature;
    9 }
    复制代码

    2.

    复制代码
    1 - (void)forwardInvocation:(NSInvocation *)invocation
    2 {
    3 SEL selector = [invocation selector];
    4
    5 if ([self.carInfo respondsToSelector:selector])
    6 {
    7 [invocation invokeWithTarget:self.carInfo];
    8 }
    9 }
    复制代码



     3.调用

    1 Car *myCar = [Car car]; //Car为一个类
    2 [(NSString *)myCar UTF8String] //这里调用NSString中的UTF8String方,注意Car中并未实现该方法

    解释: 这里借iphone开发秘籍的例子来说明, self.carInfo是一个只读的NSString对象,存在于Car类中.例子中Car实例是无法正确的为另外一个对象(NSString)实现的 选择器创建一个有效的签名。运行时当检查到当前没有有效的签名,即进入该对象(这里是myCar)的 methodSignatureForSelector:方法中,此时,将在这个方法中对每个伪继承进行迭代并尝试构建一个有效的方法签名的机会.例如代 码中,当myCar调用UTF8String时,由于无法从当前对象中获得消息,转入第二次机会捕捉消息,首先进入 methodSignatureForSelector:方法,采用迭代的方式为当前被调用的方法创建一个有效的签名,得到签名后,转入 forwardInvocation:方法对其调用的方法(UTF8String)进行实现.  forwardInvocation:中,首先获得调用的方法(UTF8String),判断self.carInfo(一个nsstring对象)能 否响应该方法,如果可以,将调用UTF8String对象的目标转换为self.carInfo对象. 这样 ,我们就实现了多继承,呵呵!!

  • 相关阅读:
    RESTful API
    访问方式由http改为https curl:(51)
    java.lang.OutOfMemoryError: PermGen space
    liunx下tomcat启动 Cannot find ./catalina.sh
    Java-编译后出现$1.class、$2.class等多个class文件
    错误处理的返回--异常还是返回值
    ubuntu 上安装温度检测
    mysql5.6不能输入中文
    jmap在ubuntu上DebuggerException: Can't attach to the process
    tomcat-reload-与内存泄露
  • 原文地址:https://www.cnblogs.com/jinjiantong/p/2979981.html
Copyright © 2011-2022 走看看