【IOS开发之Objective-C】协议和代理

在现实生活中我们存在各种各样的协议,但是都有一个共同点,就是拟定的协议,就要遵守,不遵守就是违约。在OC中也有协议这一个概念而且和我们现实生活中的协议的特点是类似的。有时我们自己想做什么事,但是现在没这个能力自己去做,亲力亲为,我们就需要找代理来帮我们做了。那么在OC中也有代理这个概念。下面就简单的说说OC中的协议和代理。

一、协议

《【IOS开发之Objective-C】对象的交互》中实现了一种对象的交互的方式。在OC中还有其他方式,比如说协议,在OC中用协议来规范接口,是实现对象之间的交互的一种机制。类似于JAVA中的接口。还可以模拟多继承。

协议的实现

第一步:使用Xcode新建一个工程;

怎么新建一个工程《【IOS开发之Objective-C】新建第一个工程-HelloWorld》

第二步:新建一个OC文件;

在这个工程里面 New File-----> Objective-C File -----> 填写文件名 – > 在File Type 里面选择“Protocol” 最后点击Next。

第三步:“拟定”协议;

假设我和某人签订和一个协议,协议里面需要我执行一个动作:每天练习一小时OC编程;那么这条协议内容就是:       - (void)aDayCodeOneHour;这只是一个协议条款,协议自己本身事没有能力遵守协议或是实现协议。

#import <Foundation/Foundation.h>

@protocol MyProtocol <NSObject>

- (void)aDayCodeOneHour;

@required  //缺省属性,必须要实现
- (void)show; //show 是必须要实现

@property (nonatomic,assign) int a;

@optional      // 可选实现
- (void)show1; //show1 是可实现也可不实现
@end

第四步:遵守协议;

新建一个Person的类,在这个类.m文件里面来实现这个方法。在实现之前需要先表明你为什么实现这个方法。那么我们就需要在Person这个类里面表明我是遵守这个协议。我们就需要在类的.h文件里面表明我是遵守这个协议的。

#import <Foundation/Foundation.h>
#import "MyProtocol.h"
@interface Person : NSObject <MyProtocol>
@property (nonatomic,assign) int a;
@end

这里我们要做两件事,第一是包好协议这个头文件,第二就是@interface Person : NSObject <MyProtocol>。接下来就是协议的实现了。在Person.m这个文件中我们简单的实现一下:

#import "Person.h"
@implementation Person
- (void)aDayCodeOneHour{
       NSLog(@"我的协议内容是“每天练习一小时OC编程”");
}
- (void)show{
       NSLog(@"这是一个协议的例子。");
}
@end

第五步:主函数中演示

#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
       @autoreleasepool {
     Person * ps = [[Person alloc] init];
        [ps aDayCodeOneHour]; //默认的也是必须要实现的
        [ps show]; //调用@required 修饰的一个方法
        ps.a = 10; //给a赋值
        NSLog(@"%d",ps.a); //取a的值打印出来

     id<MyProtocol>obj = ps; //使用di的方法表明obj就是一个对象ps
        [obj show];//obj 也调用show 这个方法
       }
    return 0;
}

我们在协议MyProtocol 里面还有几句是没有说明的:

@required 
//缺省属性,必须要实现

- (void)show;
//show 是必须要实现

@property (nonatomic,assign)int a;

@optional     
// 可选实现

- (void)show1;
//show1 是可实现也可不实现  l例子中没实现

@required 缺省属性,被他修饰的方法是必须要实现的;

@optional 可选属性,被他修饰的方法可以不实现

在协议中我们不能声明变量,但是我们可以使用属性的方法:

@property (nonatomic,assign)int a;

在协议遵守方中要实现这个,也是在.h文件中粘贴一些这条语句,系统自动会给我们生产set和get方法。

主函数就比较简单了,但是需要学习这一句:

id<MyProtocol>obj = ps;//使用id的方法表明obj就是一个对象ps的副本

[obj show];//obj也调用show
这个方法

id的这一句,这里使用一个id类遵守MyProtocol协议的对象obj,让这个对象和对象ps指向的是同一块内存区域。

怎么模拟多继承呢?

其实也不难,我们可以这么实现<协议1,协议2 > 。其实在系统库里面也有很多这样的写法。这里我就不写了。

二、代理模式

什么是代理?

代理模式是实现两个对象之间的交互的一种机制。在代理模式中涉及到两个对象,一个是主动方一个是被动方。

主动方:拟定协议,创建一个携带协议的 id 指针(指向某个具体的代理);

被动方:遵守协议,实现协议的方法。

生活情境

现在什么送外卖的很是多,每天路上都有很多发单的。我们不想取买饭,就可以叫外卖。我们可以指定哪一家吃什么?我们也不能说拿了外卖就不给钱吧,我们还需要给商家付款。这里涉及到四个问题。我买哪一家的饭?我买什么饭?我要给卖家付款。卖家需要得到他的饭款。情境拆解后就是这么几个步骤了。

①.买家的需求:我要吃饭,吃哪家的什么饭呢?

②.买家选店铺和吃什么;

③.卖家给买家送饭;

④.买家给卖家付款;

⑤.卖家得到他的饭款。

代理的实现

有了这些步骤下面实现起来就不难了。

#import <Foundation/Foundation.h>
//在主动方拟定协议
@protocol BuyFood <NSObject>
- (void)sendFood;//卖家送餐
- (void)getMoney:(int)money;//卖家得到饭钱
@end
@interface Person : NSObject
- (void)wantToEat:(NSString *)food;//买家想吃饭  什么饭
- (void)give:(int)money;//卖家给卖家多少钱
//声明一个带有协议指针的属性
@property (nonatomic,assign) id<BuyFood>delegate;
@end
#import "Person.h"
@implementation Person
- (void)wantToEat:(NSString *)food{  //选好吃什么
       NSLog(@"顾客:我想吃 %@",food);
       [self.delegate sendFood];
}
- (void)give:(int)money{ //买家付款
       //注意这里的 self.delegate
       [self.delegate getMoney:money]; //付款给给我送餐的卖家
}
@end
#import <Foundation/Foundation.h>
#import "Person.h"
@interface Rooom : NSObject <BuyFood>
- (void)show;
- (void)wantToGetMyMoney;
@end

#import "Rooom.h"
@implementation Rooom
{
       int  _money;
}
- (void)sendFood{ //卖家送餐
       NSLog(@"店家:好的我马上给您派送");
}
- (void)getMoney:(int)money{
       _money = money; //卖家得到饭钱就放进他自己的口袋了
}
- (void)wantToGetMyMoney{
 //卖家想得到饭钱就需要买家付款  买家付款给对应的卖家
 //这里就是代理的回调
       Person * p1 = [[Person alloc] init];
       p1.delegate = self;   //注意这里的self  谁调用这个方法self就是谁
       [p1 give:15];       //give是主动方的方法  买家付款15元
}
- (void)show{
       NSLog(@"店家:我得到了我的money:%d",_money);
}
@end

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Rooom.h"
int main(int argc, const char * argv[]) {
       @autoreleasepool {
        Person * per = [[Person alloc] init];
        Rooom * roo = [[Rooom alloc] init];

        [per wantToEat:@"鱼香肉丝饭"];  //我想吃鱼香肉丝饭
        per.delegate = roo;              //指定代理  设置代理  选店铺
        [roo sendFood];                 //卖家送餐
        [roo wantToGetMyMoney];        //买家付款 卖家得到饭钱
        [roo show];                      //高兴的卖家 说我得到了多少钱
       }
return 0;

输出:

2015-08-03 21:41:15.656 3.代理模式[3528:303] 顾客:我想吃 鱼香肉丝饭
2015-08-03 21:41:15.673 3.代理模式[3528:303] 店家:好的我马上给您派送
2015-08-03 21:41:15.674 3.代理模式[3528:303] 店家:我得到了我的money:15

Program ended with exitcode: 0

以上就这这个情景模式的全部代码。里面有协议,有代理也有代理的回调。每一步是做什么的上面有分析,代码中也有注释。

我们再来分析:

①.买家的需求:我要吃饭,吃哪家的什么饭呢?

②.买家选店铺和吃什么       // 买家选店铺指定代理

③.卖家给买家送饭;         // 选定店铺后卖家需要做的  协议

④.买家给卖家付款;         // 给代理传值正向传值   买家给卖家付款

⑤.卖家得到他的饭款。       // 代理的回调卖家需要从买家那里得到饭钱

代理的回调

代理的回调:调用某个功能模块,这个功能模块返回一些数据,但是功能不知道具体返回给哪个对象,这个时候,我们可以通过协议规范接收者接收数据方法,这个过程就是回调。

代理的回调也在上面的情境里面可,代码上面也有。

三、总结

通过上面的具体实例,我们要知道什么是协议?什么是代理?协议和代理之间的联系。怎么去实现一个简单的协议,或是说协议的基本格式是什么?代理的基本格式是什么?代理怎么回调?

当然上面这些举例和代码是不足以使我加深对协议和代理的理解的,还需要我在工作和学习中多总结,理论联系实际。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-18 10:32:39

【IOS开发之Objective-C】协议和代理的相关文章

李洪强iOS开发之Block和协议

李洪强iOS开发之Block和协议 OC语言BLOCK和协议 一.BOLCK (一)简介 BLOCK是什么?苹果推荐的类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行. BOLCK和函数的相似性:(1)可以保存代码(2)有返回值(3)有形参(4)调用方式一样. 标识符 ^ (二)基本使用 (1)定义BLOCK变量 Int (^SumBlock)(int,int);//有参数,返回值类型为int Void (^MyBlock)()://无参数,返回值类型

iOS开发之WKWebView简单使用和常用使用场景

iOS开发之 WKWebVeiw使用 想用UIWebVeiw做的,但是突然想起来在iOS8中出了一个新的WKWebView,算是UIWebVeiw的升级版.本着对新事物的好奇,就上网查了一下,但是找了好多个都没说的多了详细,于是就问谷歌,找文档,看看使用方法,试用了一下,果然不错,记录下来,大家分享! WKWebView的特点: 性能高,稳定性好,占用的内存比较小, 支持JS交互 支持HTML5 新特性 可以添加进度条(然并卵,不好用,还是习惯第三方的). 支持内建手势, 据说高达60fps的刷

李洪强IOS开发之-iOS经典面试题

李洪强IOS开发之-iOS经典面试题 写这篇文章的目的是因为前两天同学想应聘iOS开发,从网上找了iOS面试题和答案让我帮忙看看.我扫了一眼,倒吸了一口冷气,仔细一看,气的发抖.整篇题目30多个没有一个答案是对的,总结这篇面试题的作者对iOS机制根本就是一知半解就敢发到网上,不管有心还是无心都是坑害新人.所以在这里总结一下这几年面试别人和被别人面试遇到的一些我认为比较好的基础题目分享给大家,进阶题目在后续补充.我的理解如果有错漏请一定指出,非常感谢! 从12年开始做面试官到现在已经三个年头了,这

iOS开发之Socket通信实战--Request请求数据包编码模块

实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncSocket来进行长连接连接和传输数据,该第三方地 址:https://github.com/robbiehanson/CocoaAsyncSocket,读者可以自行google或者baidu搜索 这个库的用法,网上有很多资料,而且用法不难. 在一些对Socket通信使用需求不是很高的应用中,比如需要

ios开发之NavBar和TarBar使用技巧

1  改变NavBar颜色:选中Navigation Bar 的Tint属性.选中颜色. 2  隐藏“back”按钮: self.navigationItem.hidesBackButton = YES; 3 隐藏"NavBar" : self.navigationController.navigationBarHidden = YES; 4 可以不用MainWindow.xib创建的Navigation.在每个view上自定义. 需要把每个控制页都加上以下代码来隐藏nav: -(vo

IOS开发之ZBarReaderView的使用

IOS开发之ZBarReaderView的使用 HOMEABOUTGUESTBOOKCATEGORIESTAGSLINKSSUBSCRIBE 当开发IOS程序中需要用到二维码识别功能的时候,zbar这个开源库估计会被不少人选择.但是关于zbar的用法,网上的资料大部分都集中在ZBarReaderViewController这个类的使用上.本人在使用中,发现ZBarReaderViewController这 个类使用很不灵活,比如,如果需要对界面做一些自定义的定制时会变得很麻烦.在zbar的头文件

IOS开发之copy的问题

copy的目的就是修改副本,修改原始对象和副本时不会产生干扰. 定义一个不可变属性A,再定义一个可变属性B.用B做添加删除等操作后再将B赋值给A时,有些人习惯用A = B:其实这样是不安全的. 假设有下面的一段代码: ? 1 2 3 4 5 6 7 8 9 10   int main() {    NSMutableString *strM = [NSMutableString [email protected]"123"];    NSString *str = strM;    N

iOS开发之Auto Layout入门

随着iPhone6与iOS8的临近,适配的问题讲更加复杂,最近学习了一下Auto Layout的使用,与大家分享.  什么是Auto Layout? Auto Layout是iOS6发布后引入的一个全新的布局特性,其目的是弥补以往Autoresizing在布局方面的不足之处,以及未来面对更多尺寸适配时界面布局可以更好的适应. 为什么要用Auto Layout? Autolayout能解决不同屏幕(iPhone4,iPhone5,iPad...)之间的适配问题. 在iPhone4时代开发者只需要适

iOS开发之CocoaPods的使用

透明色:00ff00ff //设置柱状图的颜色                ColorSet cs = new ColorSet();                cs.Id = "colorset1"; #region 设置柱状图的颜色 待开发                    string strColor = oYAXIS.Color;                    switch (strColor)                    {