ios中关于delegate(委托)的使用心得

分类: iOS开发2012-05-15 10:54 34793人阅读 评论(9) 收藏 举报
iosuiviewtimerinterfaceprinting设计模式
从开始从事OC工作到现在大概1年多了,从当初接触oc的"协议"的不明白,到现在代码中随处可见的委托,协议,其中感悟颇多。

首先,大家应该都明白的是委托是协议的一种,顾名思义,就是委托他人帮自己去做什么事。也就是当自己做什么事情不方便的时候,就可以建立一个委托,这样就可以委托他人帮自己去实现什么方法。
其次,我简单的总结了一下自己用到的委托的作用有两个,一个是传值,一个是传事件。
1.所谓传值经常用在b类要把自己的一个数据或者对象传给a类,让a类去展示或者处理。(切分紧耦合,和代码分块的时候经常用)
2.所谓传事件就是a类发生了什么事,把这件事告诉关注自己的人,也就是委托的对象,由委托的对象去考虑发生这个事件后应该做出什么反映。(这个经常见,例如在异步请求中,界面事件触发数据层改变等等)
3.利用委托赋值,这种方法感觉是为了不暴露自己的属性就可以给自己复值,而且这样更方便了类的管理,只有在你想要让别人给你赋值的时候才调用,这样的赋值更可控一些。(例如tableView中的委托(dateSource)中常见)。
最后,我想分享一下在使用委托的时候的一些心得和注意事项。
心得:delegate的命名要准确,尽量看名字就知道用法。delegate和通知有的用法有些象,但是前者是单对单的,后者是单对多的情况。
注意:在dealloc要把delegate至为nil,还有就是delegate设置属性的时候要用assign,不要用retain。
委托

在IOS中委托通过一种@protocol的方式实现,所以又称为协议.协议是多个类共享的一个方法列表,在协议中所列出的方法没有响应的实现,由其它人来实现.这叫好比我想买个手机,所以我有个buyIphone 方法,但是我不知道谁那买手机,所以把这个需求发布出去(比如公布在网站上),如果有卖手机的商人(也就是说他能实现buyIphone这个方法)看到,他就会接受我的委托,(在商人自己的类中实现<XXXdelegate>),那么我的委托对象就指向了这个商人..当我要买手机的时候,直接找他就行了.

例如:

@protocol MyDelegate
-(void)buyIphone:(NSString *)iphoneType money:(NSString *)money;@end
@interface My : NSObject
{id<MyDelegate> deleage;
}
@property(assign,nonatomic)id<MyDelegate> delegate;
@end

代码中声明了一个协议 名叫Mydelegate,在其中有一个buyIphone方法,即一个委托项。当我要购买手机的时候只需要通过delegate 调用 BuyIphone方法即可.

如下:

-(void)willbuy
{[delegate buyIphone:@"iphone 4s" money:@"4888"];}

我不必关心谁现实了这一委托,只要实现了这个委托的类,并且buyIphone是声明的委托中必须实现的方法,那么就一定能够得到结果.

例如:商人类实现了这一委托(用<Mydelegate>表示实现)

#import <Foundation/Foundation.h>
#import "My.h"
@interface Business : NSObject<MyDelegate>@end

然后在 @implementation Business 中调用 buyIphone方法

#import "Business.h"@implementation Business-(void)buyIphone:(NSString *)iphoneType money:(NSString *)money
{NSLog(@"手机有货,这个价钱卖你了,发货中!!");
}
@end
委托是Cocoa中最简单、最灵活的模式之一。委托是指给一个对象提供机会对另一个对象中的变化做出反应或者影响另一个对象的行为。其基本思想是:两个对象协同解决问题。一个对象非常普通,并且打算在广泛的情形中重用。它存储指向另一个对象(即它的委托)的引用,并在关键时刻给委托发消息。消息可能只是通知委托发生了某件事情,给委托提供机会执行额外的处理,或者消息可能要求委托提供一些关键的信息以控制所发生的事情。
 4 天前 上传下载附件 (18 KB) 委托方法通常包括3种动词:should、will、did。

should表示一个动作发生前,通常带有返回值,可以在动作发生之前改变对象状态。
will在动作发生前,委托可以对动作做出响应,但不带有返回值。
did在动作发生后做出的响应。

从方法的定义我们不难看出委托模式能够起到两方面的作用:

第一:委托协助对象主体完成某项操作,将需要定制化的操作通过委托对象来自定义实现,达到和子类化对象主体同样的作用。
第二:事件监听,委托对象监听对象主体的某些重要事件,对事件做出具体响应或广播事件交给需要作出响应的对象。

个人理解采用委托模式的好处在于:

1、避免子类化带来的过多的子类以及子类与父类的耦合
2、通过委托传递消息机制实现分层解耦

委托模式的实现思路:

1、通常是在对象主体包含一个委托对象的弱引用:
@interface A : NSObject
{
IBOutlet id delegate;
} -(id) delegate;
-(void) setDelegate:(id)obj;
2、委托对象的实现有两种方式:正式协议和非正式协议,对象主体在协议中定义委托方法,委托对象可以选择实现其中某些委托方法,因此如果通过正式协议定义委托方法需要使用@option。
@protocol NSSearchDelegate
@option
-(void)didSearchFinish:(*NSNotification) aNotification;
@end
3、连接对象主体和委托,无非就是通过setDelegate:(id)obj来实现。

4、触发委托方法。

昨天做了一个demo,用到了简单代理。

delegate是ios编程的一种设计模式。我们可以用这个设计模式来让单继承的objective-c类表现出它父类之外类的特征。昨天这个代理实现如下:

类GifView是继承自UIView的,它加载在RootViewController上来通过一个Timer播放动画。同时,RootViewController需要知道Timer的每次执行。

代码如下。

首先,定义GifView,在其头文件中定义代理EveryFrameDelegate,同时声明方法- (void)DoSomethingEveryFrame;

#import <UIKit/UIKit.h>@protocol EveryFrameDelegate <NSObject>- (void)DoSomethingEveryFrame;@end@interface GifView : UIView
{NSTimer *timer;id <EveryFrameDelegate> delegate;NSInteger currentIndex;
}@property (nonatomic, retain) id <EveryFrameDelegate> delegate;@end

然后,只要在GifView.m中让Timer在每次执行的时候调用delegate来执行DoSomethingEveryFrame,代码如下

- (id)initWithFrame:(CGRect)frame
{self = [super initWithFrame:frame];if (self){timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(play) userInfo:nil repeats:YES];[timer fire];}return self;
}-(void)play
{[delegate DoSomethingEveryFrame];}

GifView上的工作就完成了。

下面是RootViewController中的代码,RootViewController只要在定义GifView的时候指定其代理为自身,就可以知道Timer的每次执行:

- (void)viewDidLoad
{[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.CGRect rect = CGRectMake(0, 0, 200, 200);GifView *tmp = [[GifView alloc] initWithFrame:rect];tmp.delegate = self;[self.view addSubview:tmp];[tmp release];
}- (void)DoSomethingEveryFrame
{NSLog(@"I'm the delegate! I'm doing printing!");
}

GifView中Timer每次执行都会打印一行

I'm the delegate! I'm doing printing!

故,RootViewController就知道Timer的每次执行了。

做程序时,经常会碰到这样一种情况:在对象A中有一个对象B,在B中做某个操作时需要调用A对象的某个方法。这时,我们就需要用代理机制,也叫委托机制。

还记得刚接触面向对象的时候,居然在B对象中又alloc了一个A对象,发现执行方法时没有works,那时不理解新alloc的对象和原来的对象A不是一个东东。
今天专门补习了一下哈,在网上找了一些资料,综合了一下,写了这篇菜鸟教程。

委托代理(delegate),顾名思义,把某个对象要做的事情委托给别的对象去做。那么别的对象就是这个对象的代理,代替它来打理要做的事。反映到程序中, 首先要明确一个对象的委托方是哪个对象,委托所做的内容是什么。委托机制在很多语言中都用到的,这只是个通用的思想,网上会有很多关于这方面的介绍。

下面以一个简单的例子介绍一下委托:

一、新建iPhone项目DelegateDemo;

二、添加UIView类ViewA;

三、ViewA.h的内容如下:

[cpp] view plaincopy
  1. #import <UIKit/UIKit.h>
  2. @protocol <a href="http://www.wuleilei.com/" target="_blank"><span style="color:#ff0000">ViewADelegate</span></a>; //申明代理协议
  3. @interface ViewA : UIView {
  4. id <<a href="http://www.wuleilei.com/" target="_blank"><span style="color:#ff0000">ViewADelegate</span></a>> _viewADelegate;
  5. }
  6. @property (nonatomic, assign) id viewADelegate; //定义代理的属性,同时要在.m加中
  7. @end
  8. //代理协议的内容
  9. @protocol <a href="http://www.wuleilei.com/" target="_blank"><span style="color:#ff0000">ViewADelegate</span></a> <NSObject>
  10. - (void)<span style="color:#008080">viewACallBack</span>;
  11. @end
  12. View.m中:
  13. <span> </span>@synthesize viewADelegate = _viewADelegate;

三、在DelegateDemoViewController.m中:

- (void)viewDidLoad {ViewA *viewA = [[ViewA alloc] initWithFrame:CGRectMake(50, 100, 200, 100)];viewA.viewADelegate = self; //设置viewA的代理为当前对象自己[self.view addSubview:viewA];[viewA release];[super viewDidLoad];
}- (void)viewACallBack {NSLog(@"Hi, I am back!");
}

四、

点击此处下载示例。

  • 上一篇iOS开发之异步加载图片
  • 下一篇ios开发中类方法以及self的注意点

ios中关于delegate(委托)的使用心得相关推荐

  1. 转:终于会用c#中的delegate(委托)和event(事件)了

    第一个例子: public class DelegateTest {// 声明delegate对象 public delegate void CompareDelegate(int a,int b); ...

  2. iOS 中delegate的理解与使用(传值)

    之前做了半年的iOS,刚入了门,又被拉去转战java,现在iOS的那位大佬离职了,又被弄过来维护app,之前对于iOS中的delegate一直都是半知半解,所以刚好趁着这个机会把我所了解的记下来,以便 ...

  3. iOS 中KVC、KVO、NSNotification、delegate 总结及区别

    iOS 中KVC.KVO.NSNotification.delegate 总结及区别 1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属 ...

  4. iOS中常见的设计模式(MVC/单例/委托/观察者)

    关于设计模式这个问题,在网上也找过一些资料,下面是我自己总结的,分享给大家 如果你刚接触设计模式,我们有好消息告诉你!首先,多亏了Cocoa的构建方式,你已经使用了许多的设计模式以及被鼓励的最佳实践. ...

  5. iOS中MVC设计模式

    在组织大型项目的代码文件时,我们常用MVC的思想.MVC的概念讲起来非常简单,就和对象(object)一样.但是理解和应用起来却非常困难.今天我们就简单总结一下MVC设计理念. MVC(Model V ...

  6. iOS中的MVC设计模式

    一.MVC概述 模型-视图-控制器(MVC)是Xerox PARC在二十世纪八十年代为编程语言Smalltalk-80发明的一种软件设计模式,已被广泛使用.后来被推荐为Oracle旗下Sun公司Jav ...

  7. iOS中MVC等设计模式详解

    iOS中MVC等设计模式详解 在iOS编程,利用设计模式可以大大提高你的开发效率,虽然在编写代码之初你需要花费较大时间把各种业务逻辑封装起来.(事实证明这是值得的!) 模型-视图-控制器(MVC)设计 ...

  8. iOS 中 XML 数据交换格式

         XML 是一种自描述的数据交换格式,但是 XML 的数据交换格式并没有 JSON 来的轻便,但是无可否认的是,XML 的应用范围也是非常广泛的,比如在 ROS(一个开源机器人操作系统)中利用 ...

  9. iOS 代理(Delegate)

    一.代理的特点 准确的说是一种软件设计模式 iOS当中以@protocol形式提现 传递方式一对一 二.代理的基本使用 代理是一种通用的设计模式,在iOS中有特定的语法来实现代理模式,OC语言可以通过 ...

最新文章

  1. Smarty中文手册,Smarty教程,Smarty模板的入门教材
  2. 限定filesize的数据泵导入导出操作案例
  3. DIB位图(Bitmap)的读取和保存
  4. Adapter(适配器)--类对象结构型模式
  5. js中自执行函数(function(){})()和(function(){}())区别
  6. artdialog子弹窗关闭父弹窗
  7. 字节跳动大规模实践埋点自动化测试框架设计
  8. Linux命令之dos2unix - 将DOS格式文本文件转换成UNIX格式
  9. JavaScript对滚动条的操作
  10. 凸优化第三章凸函数 3.6 关于广义不等式的凸性
  11. 数据清洗的主要类型及步骤
  12. html 复选框 不能选,启用或禁用html中的复选框
  13. 程序员转行去做售前、咨询
  14. 如何对磁盘分区进行写保护
  15. iOS开发系列--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开发汇总...
  16. OpenDigg iOS开源项目月报201704
  17. 2021巨量千川营销通案
  18. 计算机网络-实验5:网络层-IP协议分析
  19. js方法ajax return,AJAX_PJBLOG中用到的ajaxjs.几个简单的函数,function $(id) { return document.get - phpStudy...
  20. 通过Z-Order技术加速Hudi大规模数据集分析方案

热门文章

  1. caffe特征提取/C++数据格式转换
  2. 优化体系结构 - 解决多样性数据源
  3. centos6.5系统自带python2.6升级到python2.7
  4. 【云栖大会】探索云时代下的游戏开发模式
  5. 三款日志管理工具横向对比:Splunk vs Sumo Logic vs Logstash
  6. linux下升级 OpenSSH
  7. QtWebkit包含的类简介
  8. flink中的faker生成的数据后面带有~
  9. Flink SQL Client实现CDC实验
  10. Flink中MapFunction以及其他各种xxxFunction在intellij中的用法和规律