1.前言

自今年5月底正式转iOS之后,天天get新技能,很多技能在脑子里回旋不吐不快,所以,写点东西整理一下。先从协议代理开始。

2.协议方法的声明

@protocol EventMenuBarDelegate <NSObject>

- (void)delegateShouldDoWhenMenuButtonTapped:(UIButton *)button;

@end

以上代码意思是,利用@protocol 指令声明协议名EventMenuBarDelegate,并遵从NSObject协议,在协议中声明了一个方法

- (void)delegateShouldDoWhenMenuButtonTapped:(UIButton *)button,由于没有用@option 指令声明,所以服从该EventMenuBarDelegate的对象必须实现delegateShouldDoWhenMenuButtonTapped: 这个方法。

3.协议代理的认识

协议中声明的方法,其实就是C++等面向对象的编程语言的抽象方法,不需要具体实现过程,但是必须要声明方法接口,以用于继承该类的子类进行适配,这就是设计模式中的适配器模式。在Objective-C中,子类通过遵从协议和继承超类以达到C++的多继承的效果。我认为这样的好处就是,多态。

4.情景模拟与代码实现

委托代理其实就是某个对象需要完成某个方法所找的另外一个对象。比如,我是个懒人,我不喜欢洗衣服,我找洗衣助理帮我洗,此时,助理就是我洗衣服的委托代理,并且必须遵从洗衣协议并实现洗衣服的过程。在助理洗完之后,我再作为洗衣助理的委托代理表示感谢,向助理说谢谢并付钱。(有点绕,需要脑洞大开)如果用程序实现就可以像下面一样写。其实,这个情景中,代码模拟了两个委托代理,一个是洗衣服的协议代理,另外一个是整个业务逻辑的协议代理。

1)洗衣服的协议方法

#import <Foundation/Foundation.h>
#import "APPBLLDelegate.h" @protocol WashClothes <NSObject> - (void)washClothes:(int)num complete:(id<APPBLLDelegate>)delegate; @end

代码声明了洗衣服的协议,遵从该协议的所有对象必须完成一件事根据传入的衣服数量洗衣服,洗完之后代理我(代理)再做出响应的处理。

2)业务逻辑协议

@protocol APPBLLDelegate <NSObject>

- (void)didWashClothesSuccess:(BOOL)finished leftNum:(int)left;

- (void)didWashClotheFailed:(NSString *)errorMsg;

@end

业务逻辑的协议中,声明了两个方法,一个是洗衣成功后我需要做的,另一个是洗衣未成功我需要做的。其实,这里完全可以抽象成任何事件的协议方法,换个名字就成。比如,一次网络请求响应,一次数据库的读库写库。

而作为该业务逻辑的我(代理)而言,当洗衣助理把我当代理参数传入的时候,并不确定我的类型,仅作为一个id类型的对象指针传入,但是我必须遵循APPBLLDelegate协议,即

(id<APPBLLDelegate>)delegate

3)我(用户)的类代码实现

头文件

#import <Foundation/Foundation.h>
#import "WashClothes.h"
#import "APPBLLDelegate.h" @interface User : NSObject <APPBLLDelegate> @property int clothesNum;
@property (weak, nonatomic) id<WashClothes> delegate; - (void)askAssistantForWashingClothes; @end

我洗衣服的代理是助理,助理的类不一定是什么类,我不确定,所以用id类型来指代其类型(当然,如果确定的话就指定这个类名就好),但是助理必须遵循洗衣协议,即,

id<WashClothes> delegate

而我作为整个业务逻辑的代理,我也必须遵循业务逻辑的协议(脑洞再大点)。即,

 User : NSObject <APPBLLDelegate>

实现文件

#import "User.h"

@implementation User

- (void)askAssistantForWashingClothes {
[self.delegate washClothes:self.clothesNum complete:self];
} - (void)didWashClothesSuccess:(BOOL)finished leftNum:(int)left {
if (finished) {
NSLog(@"助理已洗完衣服,很感谢,支付洗衣费用");
} else {
NSLog(@"助理未能洗完衣服,剩余%d件", left);
}
} - (void)didWashClotheFailed:(NSString *)errorMsg {
if (errorMsg != nil) {
NSLog(@"报错:%@", errorMsg);
}
} @end

我不洗衣服,我请求助理洗衣服,那么助理必须遵循洗衣协议,并且实现其具体过程,但我不需要实现,我的任务仅是向代理发送洗衣消息。当我的助理洗完衣服之后,我作为业务逻辑的代理,我必须做出反应,比如我要说谢谢给钱,或者没洗完不给钱,再或者出现问题我要报错。

这里,业务逻辑可以抽象为一个网络请求,比如,网络状况良好,我请求成功,正确传参,正确返回。或者,网络状况良好,错误传参,错误返回。再或者,网络状况渣渣,就报错吧。。

4)洗衣助理要做的

头文件

#import <Foundation/Foundation.h>
#import "WashClothes.h" @interface Assistant : NSObject <WashClothes> @property int totalNum; - (instancetype)init; @end

洗衣助理必须遵循洗衣协议,即,

Assistant : NSObject <WashClothes>

实现洗衣方法,即,

- (void)washClothes:(int)num complete:(id<APPBLLDelegate>)delegate;

实现文件

#import "Assistant.h"

@implementation Assistant

- (instancetype)init {
self = [super init];
if (self) {
self.totalNum = ;
}
return self;
} - (void)washClothes:(int)num complete:(id<APPBLLDelegate>)delegate { int left = self.totalNum - num;
if (left > ) {
[delegate didWashClothesSuccess:YES leftNum:left];
} else {
[delegate didWashClothesSuccess:NO leftNum:abs(left)];
[delegate didWashClotheFailed:@"未能洗完衣服!"];
}
} @end

洗衣助理在初始化对象时,默认洗衣服最大数目是10件,并实现洗衣服的具体过程,洗完衣服之后给我(业务逻辑的代理)发送消息。也就是说,洗衣助理只需要洗衣服,不需要管洗完衣服做什么,剩下的将结果回传给我,让我来进行消息反馈。

5)程序单一入口

#import <Foundation/Foundation.h>
#import "User.h"
#import "Assistant.h" int main(int argc, const char * argv[]) {
@autoreleasepool { User *user = [[User alloc] init];
user.clothesNum = ; Assistant *assistance = [[Assistant alloc] init];
user.delegate = assistance; [user askAssistantForWashingClothes]; }
return ;
}

主程序创建了实例我,设置我的洗衣数量20,创建助理实例,设置我的洗衣委托代理为助理,最后向助理发送消息,助理执行洗衣服这个方法。

6)运行结果

2015-07-23 11:34:07.869 NYDelegateTest[1313:68830] 助理未能洗完衣服,剩余10

2015-07-23 11:34:07.870 NYDelegateTest[1313:68830] 报错:未能洗完衣服!

5.小结

1)Objective-C的协议可以实现适配器模式,通过继承和遵循协议,达到C++的多继承效果。通过该机制可以实现多子类的适配,使不同子类拥有各自独特的方法,匹配自身需求。

2)运用协议代理代码实现时,必须要设置实例的代理,比如,

user.delegate = assistance;

这一句必不可少,否则,代理是nil,发送消息就失效,方法不能执行,不会有任何输出。

3)这个模拟情景中,代码实现了两个协议代理。

一个是,我找助理作为我的洗衣代理。

另一个是,助理洗完衣服后,将处理结果回传给我(业务逻辑代理)。

4)在自学之初,我始终搞不清楚,table view的data source和delegate。现在才明白,其实两者都是协议代理,只不过名字不同罢了。data source的方法主要针对table view的一些UI数据源加载显示。而delegate更多的是对table view的一些操作作出响应(但是也有什么height之类的协议方法,我也是醉了,强迫症伤不起)。总之,如果单独创建table view 而不是用table view controller,data source和delegate都必须设置,且实现其协议方法。

5)文章如有理解错误,请留言交流,我会及时订正,感谢~

6)来上海之后,我两个月内成长了很多,学到很多,很感恩。我希望把我所学到明白的东西熟练应用,并能深入理解其原理,所以要学的很多很多。但是现在淡定多了。终生学习,快乐学习。谢谢帮助我的所有人 @不知霜舞哀伤udspj @280me @tinyfool ,我的美女leader @七了个六 。加油加油我可以做的更好!

iOS开发总结——协议代理的认识的更多相关文章

  1. iOS 开发之协议-代理传值

    刚开始做iOS开发的时候,对 protocol.delegate 的理解一直都是晕晕乎乎一知半解的状态,不知道两个UIViewController之间怎么进行传值. 面试过几个童鞋,问道怎么用 del ...

  2. iOS开发 中的代理实现

    iOS开发 中的代理实现 关于今天为什么要发这篇文字的原因:今天在和同事聊天的时候他跟我说项目中给他的block有时候不太能看的懂,让我尽量用代理写,好吧心累了,那就先从写个代理demo,防止以后他看 ...

  3. 浅谈iOS开发的协议(protocol)和代理(delegate)

    协议和代理对于一个新手来说确实不讨好理解,也有很多的iOS开发的老手对此是懂非懂的.网上的很多博文只是讲了怎么使用,并没有说的很明白.下面我谈一下我的理解. 1.你要先搞明白,协议和代理为什么会出现, ...

  4. 【转】iOS 开发之协议protocal-代理传值delegate

    原文网址:http://www.cnblogs.com/wzrong/p/3201938.html 刚开始做iOS开发的时候,对 protocol.delegate 的理解一直都是晕晕乎乎一知半解的状 ...

  5. Ios开发之协议protocol

    Protocol是ios开发中的一个难点也是一个重点,要想使用好,或者理解好它,可能需要时间的累积.今天我们就通过一个例子来简单的看一下,怎么样使用protocol. 我们今天用的例子就是模拟电脑插入 ...

  6. iOS开发HTTP协议相关知识总结

    HTTP原理 什么是URL URL中常见的几种协议 什么是HTTP协议 HTTP是做什么的 为什么要使用HTTP协议 HTPP协议的通信过程介绍 HTTP请求 HTTP响应 HTTP请求的选择 两种发 ...

  7. iOS开发之地图代理不起作用(提示vImage decode failed, falling back to CG path.)

    项目中用到了地图相关的东西,就把曾经的demo搬了出来,结果发现直接执行之前的demo没有问题,在xcode5下新建项目再把代码粘贴过来就会提示 May 5 11:36:21 infomedia-iP ...

  8. IOS开发之----协议与委托(Protocol and Delegate) 实例解析

    1 协议: 协议,类似于Java或C#语言中的接口,它限制了实现类必须拥有哪些方法. 它是对对象行为的定义,也是对功能的规范. 在写示例之前我给大家说下@required和@optional这两个关键 ...

  9. iOS开发 - Protocol协议及委托代理(Delegate)

    因为Object-C是不支持多继承的,所以很多时候都是用Protocol(协议)来代替.Protocol(协议)只能定义公用的一套接口,但不能提供具体的实现方法.也就是说,它只告诉你要做什么,但具体怎 ...

随机推荐

  1. c++ 博客资源

    /************************************************************** 技术博客 http://www.cnblogs.com/itdef/   ...

  2. 想到的regular方法果然已经被sklearn实现了就是L1和L2组合rugular

  3. 2018.09.09 cogs693. Antiprime数(搜索)

    传送门 看完题发现很sb. 前10个质数乘起来已经超出题目范围了. 因此只用搜索前几个质数每个的次数比较谁的因数的就行了. 代码: #include<iostream> #define l ...

  4. hfs快速搭建HTTP文件服务器

    HFS全称为http file server,他是一个专门实现文件共享的工具,通过WWW服务将要共享的目录或文件发布,从而让需要下载者直接通过IE浏览器访问发布的这个共享站点,然后随意下载共享资源.和 ...

  5. Win7 SP1 提示ADO的问题

    需要安装  Windows6.1-KB2640696-v3-x64.msu 这个Pack

  6. java 解析txt/html文件

    package util.read; import java.io.BufferedReader;import java.io.FileReader; public class ReadFromFil ...

  7. UVa 12034 Race (递推+组合数学)

    题意:A,B两个人比赛,名次有三种情况(并列第一,AB,BA).输入n,求n个人比赛时最后名次的可能数. 析:本来以为是数学题,排列组合,后来怎么想也不对.原来这是一个递推... 设n个人时答案为f( ...

  8. MySQL外键使用及说明详解

    一.外键约束 MySQL通过外键约束来保证表与表之间的数据的完整性和准确性. 外键的使用条件: 1.两个表必须是InnoDB表,MyISAM表暂时不支持外键(据说以后的版本有可能支持,但至少目前不支持 ...

  9. 整理iOS9适配中出现的坑

    一.NSAppTransportSecurity iOS9让所有的HTTP默认使用了HTTPS,原来的HTTP协议传输都改成TLS1.2协议进行传输.直接造成的情况就是App发请求的时候弹出网络无法连 ...

  10. 20155320 2016-2017-2 《Java程序设计》第五周学习总结

    20155320 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 错误处理 java中所有错误都会被打包为对象,可以通过try catch 代表错误的对象后做 ...