• Target-Action回调模式


          前面的博客中提到过回调的概念,是在OC通过协议来实现的回调,和Java中的接口的回调极为相似,下面来介绍另一种方法回调模式: Target-Action回调。首先我们来从字面意思来理解一下Target-Action回调模式,Target目标即我们要调用哪个目标对象中的方法。Action是行为的意思,就是我们要调用目标对象中的哪一个方法。委托回调模式之前在Java中接触过,而Target-Action回调模式笔者是第一次接触,可能是笔者道行太浅,感觉这是OC中对回调的新用法,感觉还行,不难理解。

            还是那句话,废话少说,用代码说问题最为直接了。下面代码是笔者根据自己的理解写的的测试demo,不足之处还请批评指正,转载或者引用请注明出处。

            在做测试的Project中,我们需要用到一个Controler和两个组件ComponentOne和ComponentTwo。为了体现出Target-Action回调模式,我们需要在组件中通过Target-Action回调模式来回调Controler中每个组件所对应的方法。为实现在组件中的回调,我们需要Controler在组件中进行注册,不然就找不到target对象和回调的方法啦。

            为了作对比,在组件1中回调的方法是不带参数的,而在组件2中回调的方法是带参数的。可能到这读者看来上面的内容感觉有点抽象,看代码来的最为直接,代码走起~

            1.首先我们先编写我们的组件1,在组件1中回调的Controler方法是不带参数的

                组件1中的接口:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //
    //  ComponentOne.h
    //
    #import <Foundation/Foundation.h>
    @interface ComponentOne : NSObject
    //记录target和action的属性
    @property (nonatomic, strong) id target;
    @property (nonatomic, assign) SEL action;
     
    //声明目标动作注册方法
    -(void) addTarget : (id)target Action : (SEL)action;
     
    //组件一的启用方法
    -(void) start;
     
    @end

            组件1的实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    //
    //  ComponentOne.m
    //
     
    #import "ComponentOne.h"
     
    @implementation ComponentOne
    //实现组件中的注册方法
    -(void)addTarget:(id)target Action:(SEL)action
    {
        self.target = target;
        self.action = action;
    }
    //实现组件的启动方法
    -(void)start
    {
        //回调target对象中的action方法
        [self.target performSelector:_action];
    }
    @end

            代码说明:

                1.属性target用于接收Controler的对象,也就是要回调的目标对象。

                2.属性action用于接收目标对象的方法,也就是要在目标对象中要回调的方法

                3.addTarget: Action:方法用于注册目标动作,说白了目标对象和目标对象的方法是通过这个方法传入到组件中的

                4.start函数负责回调目标对象中的方法

        2.组件1完事以后我们就开始编写我们的组件2啦,组件2和组件1中唯一不同的地方是回调的方法需要组件2提供参数,下面就只给出不同的部分代码:

    1
    2
    3
    4
    5
    //组件二的启动方法
    -(void)start
    {
        [self.target performSelector:self.action withObject:@"*组件二中返回的参数*"];
    }

            代码说明: 在回调Controler方法的时候,需要组件2提供参数,然后再回调

        ​3.组件写好了,接下来我们就开始装配了,下面我们就开始编写我们的Controler方法,来完成组装任务,并且给每个组件提供相应的回调方法。在每个回调方法中就开始编写我们的业务逻辑,同时也可以根据组件提供的参数来实现我们的特定业务逻辑。下面就是我们的Controler的实现部分。

        ​    ​装配时为了隐藏我们的组件,我们在实现文件中用延展来装配我们的组件,假定在Controler中要使用我们的组件1、2,Controler中的代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    #import "Controler.h"
    #import "ComponentOne.h"
    #import "ComponentTwo.h"
    //在Controler中使用ComponentOne组件和ComponentTow组件
    //为了隐藏Controler内部组件,我们用延展进行组件的声明和调用
    @interface Controler ()
    //声明组件
    @property(nonatomic, strong) ComponentOne *oneComponent;
    @property(nonatomic, strong) ComponentTwo *twoComponent;
     
    //声明Controler中的方法,用于组件的回调
    //声明组件一中回调的方法,无惨方法
    -(void)componentOneFunction;
     
    //声明组件二中的回调方法,有参方法
    -(void)componentTwoFunction : (NSString *)strValue;
    @end
     
     
     
    //-----------------------实现部分---------------------------
    @implementation Controler
    //进行组件的初始化并注册回调方法
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            //给组件一分配内存空间
            self.oneComponent = [[ComponentOne alloc] init];
            //注册组件一的回调方法
            [self.oneComponent addTarget:self Action:@selector(componentOneFunction)];
            //启动组件一
            [self.oneComponent start];
             
            //给组件二分配内存空间
            self.twoComponent = [[ComponentTwo alloc] init];
            //注册组件二的回调方法
            [self.twoComponent addTarget:self Action:@selector(componentTwoFunction:)];
            //启动组件二
            [self.twoComponent start];
        }
        return self;
    }
     
     
    //实现controler中的回调方法
    -(void)componentOneFunction
    {
        NSLog(@"我是Controler中的componentOneFunction方法,我是在组件一中回调使用的");
    }
     
    -(void)componentTwoFunction:(NSString *)strValue
    {
        NSLog(@"我是Controler中的componenTwoFunction方法,我的参数%@是从组件二中回调时获取的", strValue);
    }
     
    @end

        ​    ​代码说明:

        ​    ​    ​    ​1.在Controler中我们声明并实例化了我们要使用的组件模块

        ​    ​    ​    ​2.在Controler中声明和实现组件中Controler对象要回调的方法

        ​    ​    ​    ​3.在组件实例化后我们要再组件中注册我们要调用Controler中的那个方法。

        ​    ​    ​    ​4.注册后,我们就可以启动组件来测试组件功能

        ​4,在mian函数中我们为了测试,把Controler进行实例化,代码如下:

    1
    2
    //controler的实现
     Controler *controler = [[Controler alloc] init];

        ​    ​上面代码的运行结果如下:

    1
    2
    2014-08-18 08:33:23.900 Test2[544:303] 我是Controler中的componentOneFunction方法,我是在组件一中回调使用的
    2014-08-18 08:33:23.902 Test2[544:303] 我是Controler中的componenTwoFunction方法,我的参数*组件二中返回的参数*是从组件二中回调时获取的
  • 相关阅读:
    网页游戏中PK系统的实现
    操作系统面试题
    9.26<立方网>技术笔试题
    cocos2d-x游戏之2048
    适配器模式
    工厂模式的三种形式
    面向对象设计的几大原则
    数据库的优化
    @RequestBody的使用
    vue.js小记
  • 原文地址:https://www.cnblogs.com/zhangkeyu/p/6659430.html
Copyright © 2020-2023  润新知