zoukankan      html  css  js  c++  java
  • iOS&谁说我不能执行你

    写完标题,我也扑通一笑.就先来对标题透一下剧吧.

      "谁说我不能执行你":应该把"我"与"你"理解成OC语言中不同类的实例对象.<IT男永远不孤单,因为IT男搞的就是面向对象编程>

      是的,在今天之前,我是不相信:我能执行你.但是,现在我相信了,没想到我是如此的强大,只是我没有发现而已!

      之前,我一直是这样认为的:在iOS开发中,A类的对象a,是不能去执行B类中的实例方法的.其实不是这样的.

      的确,在iOS中,是没有多继承的,只有单继承.在其它语言中,很容易实现两个不同类的对象去拥有同一个方法,因为他们是多继承的,他们就好比两个男生能拥有同一个妹子一样.iOS就没那么泛滥,是很单纯的,因为只有单继承.

      现实中,需求是千奇百怪的.特殊情况,需要特殊处理.有时候在iOS开发中,也需要A类的对象a去执行B类中的实例方法.为了达到这一点,先来介绍一下消息转发机制.

    消息转发

      其实,当向某个对象发送某个消息时,runtime system在当前和父类中都找不到对应的实现方法是,runtime system并不会立即报错误使程序崩溃,而是依次执行下列步骤: 

           

      1,动态方法

      像当前类发送+ (BOOL)resolveInstanceMethod:(SEL)sel信号,检查是否动态向该类添加了方法.可进入这个博客查看:http://blog.csdn.net/haishu_zheng/article/details/12873151

      2,快速消息转发

      检查该类是否实现了- (id)forwardingTargetForSelector:(SEL)aSelector方法,若实现了则调用这个方法.若该方法返回值对象非nil或者分self,则向该返回对象从新发送消息.

      3,标准消息转发

      runtime发送- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector消息获取selector对应方法签名.返回值非空则通过- (void)forwardInvocation:(NSInvocation *)anInvocation转发消息,返回值为空则像当前对象发送doesNotRecognizeSelector:消息,程序崩溃退出.

      总结:能用以上2,3方式实现消息的转发.

    快速消息转发

    快速消息转发的实现方法很简单,只需要重写 - (id)forwardingTargetForSelector:(SEL)aSelector  方法即可。
    我来举个简单的例子,比如现有2个类:Teacher 和 Doctor,Doctor可以做手术(operate方法)。

    Teacher.h

    #import <Foundation/Foundation.h>

    @interface Teacher : NSObject

    @end

    Teacher.m

    #import "Teacher.h"

    #import "Doctor.h"

    @implementation Teacher

    - (id)forwardingTargetForSelector:(SEL)aSelector {

        Doctor* doctor = [[Doctor alloc] init];

        if ([doctor respondsToSelector:aSelector]) {

            return doctor;

        }

        return nil;

    }

    @end

    Doctor.h

    #import <Foundation/Foundation.h>

    @interface Doctor : NSObject

    - (void)operate;

    @end

    Doctor.m

    #import "Doctor.h"

    @implementation Doctor

    - (void)operate; {

        NSLog(@"operate");

    }

    @end

    到这里还差一步,再弄一个分类.具体是为什么,自己想.

    Teacher+DoctorMethod.h

    #import "Teacher.h"

    @interface Teacher (DoctorMethod)

    - (void)operate;

    @end

    Teacher+DoctorMethod.m

    #import "Teacher+DoctorMethod.h"

    @implementation Teacher (DoctorMethod)

    @end

    ok,现在可以到main.m中了

    #import <Foundation/Foundation.h>

    #import "Teacher.h"

    #import "Teacher+DoctorMethod.h"

    int main(int argc, const char * argv[]) {

        @autoreleasepool {

            Teacher* teacher = [[Teacher alloc] init];

            [teacher operate];

        }

        return 0;

    }

     log:2015-04-26 17:45:45.134 Quichly[3304:381361] operate

    成功了!

    标准消息转发 <待续...>

  • 相关阅读:
    重链剖分的总结与模板
    PBDS学习笔记(一)
    LCT 第一题 洛谷模板
    2018年暑假第四次周赛-图论部分题解
    后缀数组求不同子串的个数
    Codeforces Round #106 (Div. 2) Coloring Brackets(区间DP)
    Codeforces Round #510 (Div. 2) D. Petya and Array (权值线段树)
    HDU 3974 Assign the task (dfs序+线段树)
    Manthan, Codefest 18 (rated, Div. 1 + Div. 2) D.Valid BFS? (模拟)
    POJ
  • 原文地址:https://www.cnblogs.com/iOS771722918/p/4458109.html
Copyright © 2011-2022 走看看