OC教程5-委托delegate模式回调

OC5-委托模式回调

本章主要讲解委托模式已经通过委托模式实现的回调接口。

1,委托模式

委托模式是OC语法独有的开发模式。是基于组件拼装的一种快速开发模式。该模式下,可以保证组件的高度灵活性和通用性。属于组件的一种开放式接口。

下面通过一个现实生活中的场景简单理解下委托模式的应用。

例如我们现在有一个公司。公司想要进行IPO。可是公司老总并不熟悉资本操作,这时候就需要委托一个人或者一个机构来作这件事。

公司首先要提出能做IPO这件事的详细要求,然后在通过猎头寻找合适的人选。

用代码描述应该是这样的:

  • 首先用协议描述公司的用人要求
  • 声明一个遵守该协议的属性,这个属性应该由外界赋值,比如猎头公司
  • 在公司要上市的时候,本质上有遵守协议的onePerson来做这件事。到底谁是onePerson不重要,重要的是他有上市的方法。
//公司的用人协议
@protocol CompanyProtocol <NSObject>

-(void)doIPO;

@end

//公司类的声明
@interface Company : NSObject

@property(nonatomic,strong)id<CompanyProtocol>onePerson;

-(void)stratIPO;
@end

//公司类的实现
@implementation Company

-(void)stratIPO
{
        if(self.onePerson)
        {
            [self.onePerson doIPO];
        }
}

@end

公司的声明代码中有一个属性。这种模式和复合开发模式有些相似,但本质上不同。

我们拿之前通过复合模式开发的高级空调来分析。在准备要开发高级空调的时候,除甲醛的模块已经存在,所有直接声明一个除甲醛的属性并且在初始化的时候为这个属性分配内存,就可以让空调具有除甲醛的功能。

但在描述公司的时候,我们并不知道,谁能够带领公司进行IPO,但是不能因为一个人岗位的人选没有确定,而整个公司停止运转。所有采用委托的方式,将这件事进行外包处理。公司不关心具体是哪个对象做的,但是关系这件事是否能完成。

下面我们来创建一个可以完成上市操作的对象,让其帮助公司完成上市任务。

@interface Finance : NSObject <CompanyProtocol>

@end

@implementation Finance

-(void)doIPO
{
        NSLog(@"开始上市!");
}

@end

现在公司和能带领公司的人都齐全,就可以进行下一步开发了。

main()
{
        Finance * per = [[Finance alloc] init];
        Company * company = [[Company alloc] init];

        company.onePerson = per;

        [company startIPO];//当公司开始IPO时,本质上是调用Finance对象per的doIPO方法。
}

虽然从代码上面看,是公司进行IPO,但开发本质是公司委托per对象进行IPO操作。这样的模式就是委托模式。

2,委托回调

委托模式的实现较为复杂,且需要根据实际应用场景进行设计。但之后我们使用的并不多,在这里制作简单了解即可。

委托回调模式是基于委托模式基础上进行的事件反馈接口封装。

仍然那上一章的开关作为讲解案例。上一章我们已经知道回调的概念,已经回调的意义。核心就是让组件的状态能够及时反馈到使用者。在目标动作模式下通过配置组件的回调对象和回调方法来监控组件的状态。

本章的委托回调模式,则是通过设置组件的委托人和实现委托方法来监控组件的状态。

委托(代理)人:从上文中公司上市的例子可以看出,公司委托财务人员进行上市操作。所以,从公司的角度看,财务人员是公司的委托人。从上市这个操作来说,财务人员是公司的代表,也称代理人。委托人和代理人本质上是一个意思,只是从不同角度对同一个对象的不同描述。

委托(代理)方法:公司通过协议来声明委托人的行为。作为公司的委托人,当然必须具有这些行为。协议中声明的方法从公司角度说是委托方法,从财务人员角度来说是代理方法。

通常组件需要通过委托方法反馈自身状态信息。使用者如果想监控组件状态,只需作为组件的委托人,并且实现委托方法即可。

下面我们用开关做例子进行代码的讲解。

  • 阅读开关的声明文件,确定委托人属性以及委托方法
  • 将开关作为房间的组件,声明属性并分配内存
  • 设置开关的委托人并实现委托方法

开关的声明文件

@protocol  SwitchDelegate;//前向声明,告知编译器SwitchDelegate为一个协议

@interface SwitchD : NSObject

typedef enum : NSUInteger {
    SwitchStateOff,//default
    SwitchStateOn,
} SwitchState;

@property(nonatomic,assign,readonly)SwitchState currentState;

@property(nonatomic,weak)id<SwitchDelegate>delegate;

@end

@protocol  SwitchDelegate <NSObject>
//当开关状态改变是,会调用委托人的此方法进行状态反馈。
-(void)switchD:(SwitchD *)s didChangeState:(SwitchState)currentState;

@end

房间的声明文件.h

@interface Room : NSObject <SwitchDelegate>

@end

房间的实现文件.m

@interface Room ()<SwitchDelegate>

@property (strong, nonatomic) Light *aLight;
@property (strong, nonatomic) SwitchD *aSwitch;

@end

@implementation Room

- (instancetype)init
{
    self = [super init];
    if (self)
    {
        self.aLight = [[Light alloc] init];

        self.aSwitch = [[SwitchD alloc] init];
        //设置开关的委托人为自己(Room对象)
        self.aSwitch.delegate = self;
    }
    return self;
}

- (void)switchD:(SwitchD *)s didChangeState:(SwitchState)currentState
{
    if (currentState == SwitchStateOff)
    {
        [self.aLight turnOff];
    }
    else
    {
        [self.aLight turnOn];
    }
}

@end

通过上述代码,可以看出,当开关状态改变的时候,开关对象会调用Room实现的委托方法。通过在委托方法内部的代码,实现对开关状态的反馈进行处理。

3,委托回调与目标动作回调

我们现在已经接触两种回调模式,这里讲解一下其中的不同和使用场景。

目标动作回调属于简单组件的状态回调。其特点是灵活,用户可以自己制定回调方法,但同时这也是目标动作回调的劣势。由于可以自己指定回调方法,在回调时便无法对回调参数给出明确的声明。所有,目标动作回调通常带有一个参数,即触发回调方法的对象本身,其他参数需要通过对象本身的属性继续获取。

委托模式回调属于复杂组件回调。其特点是回调方法提前被协议声明好了。所有可以规定其回调参数,适合携带参数的事件回调。在App开发中,一般的事件都会携带参数,所以,具有委托回调模式接口的组件更加常见。

但委托回调也有自己的不足之处,就是如果一个类内同时有两个相同类型的组件。那么这两个组件的回调方法也是相同的,我们就需要在方法内进行判断,是哪一个组件回调了委托方法。无法实现每个组件的独立回调。在下一章的代码块回调中,这个问题被完美解决。

时间: 2024-08-28 04:20:09

OC教程5-委托delegate模式回调的相关文章

OC教程6-代码块block回调

OC6-代码块回调 本章教程主要对代码块回调模式进行讲解,已经分析其他回调的各种优缺点和适合的使用场景. 代码块机制 Block变量类型 Block代码封装及调用 Block变量对普通变量作用域的影响 Block回调接口使用 1,代码块机制 苹果公司在iOS4 SDK中首次支持代码块机制,随后代码块机制被广泛应用于各种编码场景,最常见的为回调机制,也成为Block回调. 代码块也称Block.是封装代码的一种机制,也可以称为匿名函数. 使用这种机制可以将一段代码放入一个Block变量中进行存储,

OC3大回调模式使用总结(二)委托模式回调

OC 3大回调模式使用总结(二)委托模式回调 1.委托模式回调 主要用于 UITableView(UITableViewController),UICollectionView,UIPickerView,UITextField,UITextField 这几类控件,是使用委托模式封装的,使用方法和按钮类的控件不一样 委托模式,实际上也是一种对自身状态的汇报机制,某个状态或者事件的变化是不确定时间发生的,但是发生的时候就就得有某些应对措施,这些应对措施是提前写在协议中的; 与目标动作回调不同的是,委

[objective-c] 05 - 委托模式回调

本章主要讲解委托模式以及通过委托模式实现的回调接口. 1.委托模式 委托模式是OC语法独有的开发模式.是基于组件拼装的一种快速开发模式.该模式下,可以保证组件的高度灵活性和通用性.属于组件的一种开放式接口. 下面通过一个现实生活中的场景简单理解下委托模式的应用. 例如我们现在有一个公司.公司想要进行IPO.可是公司老总并不熟悉资本操作,这时候就需要委托一个人或者一个机构来作这件事. 公司首先要提出能做IPO这件事的详细要求,然后通过猎头寻找合适的人选. 用代码描述应该是这样的: 首先用协议描述公

OC教程4目标动作回调-Target Action

OC4-目标动作回调 本章主要讲解回调的概以及具有目标动作回调接口的组件如何使用. 1,回调 回调,也叫事件触发,在底层开发中也就服务或中断服务.其产生过程较为复杂,所有我们再次不会展开讲解.只是单纯讲解如果配置回调. 在使用一些较为复杂,或者和用户有交互类型的组件时.我们通常需要根据组件触发的事件来做出相应的响应. 比如我们使用一个开关控制一个灯.我们在编写代码的时候并不能准确的知道开关的状态,也就无法确定灯的状态.所有我们只能在开关状态发送改变的时候,获取开关的状态且根据开关的状态对灯的状态

swift详解之十一------------协议、委托(代理)模式

协议.委托(代理)模式 注:本小节总结协议以及依靠协议实现委托,这将在以后经常被使用.是一个非常重要的模块 看下官方的定义:协议定义了一个蓝图 , 规定了用来实现某一特定工作或者功能所必须的方法和属性,类.结构体.或者枚举类型都可以遵循协议, 并提供具体实现来完成协议定义的方法和功能 . 任意能够满足协议要求的类型都被成为遵循了这个协议 1.协议的语法 协议的关键字:protocol 协议的语法: protocol Pro1{ //这里定义属性或者方法 } 要使一个类或者结构体遵循某个协议 ,

OC学习篇之---代理模式

在前一篇文章我们介绍了OC中的协议的概念:http://blog.csdn.net/jiangwei0910410003/article/details/41776015,这篇文章我们就来介绍一下OC中的代理模式,关于代理模式,如果还有同学不太清楚的话,就自己去补充知识了,这里就不做介绍了,这里只介绍OC中是如何实现代理模式的. 这里举一个简单的例子: 小孩类,护士类,保姆类,其中小孩类有两个方法:wash和play 这里代理对象就是:护士类.保姆类,小孩类是被代理对象. 看一下代码: 首先看一

黑马程序员_ 利用oc的协议实现代理模式

先说下代理模式是什么吧 定义: 为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象 而代理对象可以在客户端和目标对象之间起到中介的作用. 在看过李明杰老师的课程后,我对代理模式有了最初步的理解,虽然还很浅显 但是也明白了代理模式的 一些作用跟用法.首先使用代理模式可以降低耦合度.大大的增强了代码的弹性. 举个例子,小明想看电影,但是没时间买票 于是就拜托小强去买票 最简单的方式就是 建立一个person类(小明) 一个agent类(代理类) ag

C#用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程

C#用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程C# 2011-03-05 13:06:24 阅读19 评论0   字号:大中小 订阅 用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程 在C#中使用线程的方法很多,使用委托的BeginInvoke和EndInvoke方法就是其中之一. BeginInvoke方法可以使用线程异步地执行委托所指向的方法.然后通过EndInvoke方法获得方法的返回值(EndInvoke方法的返回

(转载)OC学习篇之---代理模式

在前一篇文章我们介绍了OC中的协议的概念,这篇文章我们就来介绍一下OC中的代理模式,关于代理模式,如果还有同学不太清楚的话,就自己去补充知识了,这里就不做介绍了,这里只介绍OC中是如何实现代理模式的. 这里举一个简单的例子: 小孩类,护士类,保姆类,其中小孩类有两个方法:wash和play 这里代理对象就是:护士类.保姆类,小孩类是被代理对象. 看一下代码: 首先看一下小孩类: Children.h 1 // 2 // Children.h 3 // 12_DesignStyle 4 // 5