【IOS 开发学习总结-OC-21】★★★objective-c面向对象——委托/代理(delegate)
2015-09-27 19:59
651 查看
本文建议结合上篇博文一起学习: 【IOS 开发学习总结-OC-20】★★★objective-c面向对象——协议(protocol)
2.委托者声明一个属性——用于代表被委托者,一般建议用id类型。注意:这个属性是弱引用——为什么是弱引用,会在后面说明。
3.被委托者声明实现了委托里的协议
4.设置委托——在被委托者里设置自身是委托者的被委托者。
5委托事件——在被委托者里调用委托的方法
HXYBoss.h
HXYBoss.m
HXYSec.h
HXYSec.m
main.m
编译运行结果:
即:有A,B两个Object, A中有一个B的实例变量,B中又有一个A的实例变量,要release A就必须releaseA中的B,而要release B有必须release B中的A,这样就产生了一个Retain Circle,A B都不能被dealloc.解决Retain Circle的方法就是使用弱引用(weak reference),弱引用没有被引用的那个Object的所有权,也就不需要release它,从而解决了Retain Circle问题.为了防止Retain Circle的发生, delegate通常都是弱引用的, 因此我们一般不应该retain一个delegate。
NSURLConnection是个例外。
1.传递事件
传递事件就是A发生了什么事情, 希望B知道下, 然后B在自己的类里面要做出某些反应.典型的如
2.确定事件可执行
确定事件可执行是当A需要执行某个事件的时候, A不确定到底可执行, 这个时候希望B能回应下. 如
3.传递值
传递值是当A需要某个数据的时候, 由B来提供. 例子还是UITableView里的,
通常的委托用delegate做后缀.如
数据源
当你的委托的方法过多, 可以拆分数据部分和其他逻辑部分, 数据部分用dataSource做后缀. 如
通常的委托只支持一对一的委托, 但是在某些场景下, 我们希望有多个被委托者. 这种场景下可以考虑使用多播委托.
多播委托的实现类在XYMulticastDelegate, https://github.com/uxyheaven/XYQuick/tree/master/XYQuick/event/modules.
他是copy form XMPP的GCDMulticastDelegate.
每个多播委托的委托者类建议有以下的基本描述
实现文件里, 你需要这么写
其他的用法和普通的delegate类似
本文建议结合上篇博文一起学习: 【IOS 开发学习总结-OC-20】★★★objective-c面向对象——协议(protocol)
参考资料:
1./article/1822252.html
2.http://www.jianshu.com/p/b6434c2997d1
3.http://leopard168.blog.163.com/blog/static4./168471844201306114533858/
4.https://github.com/robbiehanson/XMPPFramework
delegate 是什么
协议和委托/代理关系很密切,代理是种设计模式。delegate是委托/代理模式.委托/代理模式是将一件属于委托者做的事情,交给另外一个被委托者来处理. 为了便于理解,这里都成为统一称为委托(delegate)。一个标准的委托由如下内容组成:
1.协议的声明——用来声明哪些方法被委托出去#import <Foundation/Foundation.h> @protocol SecDelegate <NSObject> -(void)phone;//打电话 -(void)payoff;//发工资 @end
2.委托者声明一个属性——用于代表被委托者,一般建议用id类型。注意:这个属性是弱引用——为什么是弱引用,会在后面说明。
@property (weak,nonatomic)id<SecDelegate>delegate;
3.被委托者声明实现了委托里的协议
@interface HXYSec : NSObject<SecDelegate>
4.设置委托——在被委托者里设置自身是委托者的被委托者。
boss.delegate=sec;//将被委托者自己的实例作为被委托对象
5委托事件——在被委托者里调用委托的方法
[boss.delegate phone]; [boss.delegate payoff]; //或者是 [sec phone]; [sec payoff];
示例代码:
SecDelegate.h#import <Foundation/Foundation.h> @protocol SecDelegate <NSObject> -(void)phone;//打电话 -(void)payoff;//发工资 @end
HXYBoss.h
#import <Foundation/Foundation.h> #import "SecDelegate.h" @interface HXYBoss : NSObject @property (strong,nonatomic)NSString * name; @property (weak,nonatomic)id<SecDelegate>delegate; // 一般建议用id类型 -(void)talk;//谈心 @end
HXYBoss.m
#import "HXYBoss.h" @implementation HXYBoss @synthesize name; -(void)talk { NSLog(@"%@在谈话!",name); } @end
HXYSec.h
#import <Foundation/Foundation.h> #import "HXYBoss.h" @interface HXYSec : NSObject<SecDelegate> @property (strong,nonatomic)NSString * name; @end
HXYSec.m
#import "HXYSec.h" @implementation HXYSec @synthesize name; -(void)phone { NSLog(@"%@在打电话!",name); } -(void)payoff { NSLog(@"%@在发工资!",name); } @end
main.m
#import <Foundation/Foundation.h> #import "HXYBoss.h" #import "HXYSec.h" int main(int argc, const char * argv[]) { @autoreleasepool { HXYBoss *boss=[[HXYBoss alloc]init]; boss.name=@"韩新源"; HXYSec *sec=[[HXYSec alloc]init]; sec.name=@"李秘书"; [boss talk]; boss.delegate=sec; [boss.delegate phone]; [boss.delegate payoff]; //或者是 [sec phone]; [sec payoff]; } return 0; }
编译运行结果:
2015-09-28 09:48:15.022 代理[1312:34897] 韩新源在谈话! 2015-09-28 09:48:15.023 代理[1312:34897] 李秘书在打电话! 2015-09-28 09:48:15.023 代理[1312:34897] 李秘书在发工资! 2015-09-28 09:48:15.024 代理[1312:34897] 李秘书在打电话! 2015-09-28 09:48:15.024 代理[1312:34897] 李秘书在发工资!
delegate为什么用弱引用
答案是:为了避免retain cycle。即:有A,B两个Object, A中有一个B的实例变量,B中又有一个A的实例变量,要release A就必须releaseA中的B,而要release B有必须release B中的A,这样就产生了一个Retain Circle,A B都不能被dealloc.解决Retain Circle的方法就是使用弱引用(weak reference),弱引用没有被引用的那个Object的所有权,也就不需要release它,从而解决了Retain Circle问题.为了防止Retain Circle的发生, delegate通常都是弱引用的, 因此我们一般不应该retain一个delegate。
NSURLConnection是个例外。
delegate 的3个用途
委托一般可以分成3种1.传递事件
传递事件就是A发生了什么事情, 希望B知道下, 然后B在自己的类里面要做出某些反应.典型的如
tableView:didSelectRowAtIndexPath:, 就是UITableView点击了某个cell的时候, 希望其它类(通常是ViewController)响应这个点击, 在点击的时候跳转到其他viewController之类的.
2.确定事件可执行
确定事件可执行是当A需要执行某个事件的时候, A不确定到底可执行, 这个时候希望B能回应下. 如
tableView:shouldHighlightRowAtIndexPath:是UITableView询问其它类要不要高亮显示某个cell, 当返回NO的时候, 就UITableView就不会执行cell的高亮方法.
3.传递值
传递值是当A需要某个数据的时候, 由B来提供. 例子还是UITableView里的,
tableView:cellForRowAtIndexPath:是需要某个cell的时候由其他类提供这个cell.
委托命
委托通常的委托用delegate做后缀.如
<UIScrollViewDelegate>
@protocol <#class#>Delegate
数据源
当你的委托的方法过多, 可以拆分数据部分和其他逻辑部分, 数据部分用dataSource做后缀. 如
<UITableViewDataSource, UITableViewDelegate>
@protocol <#class#>DataSource
多播委托
多播委托通常的委托只支持一对一的委托, 但是在某些场景下, 我们希望有多个被委托者. 这种场景下可以考虑使用多播委托.
多播委托的实现类在XYMulticastDelegate, https://github.com/uxyheaven/XYQuick/tree/master/XYQuick/event/modules.
他是copy form XMPP的GCDMulticastDelegate.
每个多播委托的委托者类建议有以下的基本描述
// .h // 多播委托, 建议加上你的协议修饰: -(id <InAppPurchasesServiceProtocol>)multicastDelggate; - (id)multicastDelggate; - (void)addDelegate:(id)delegate; - (void)removeDelegate:(id)delegate; - (void)removeAllDelegates;
实现文件里, 你需要这么写
// .m - (void)addDelegate:(id)delegate { [_multicastDelggate addDelegate:delegate delegateQueue:dispatch_get_main_queue()]; } - (void)removeDelegate:(id)delegate { [_multicastDelggate removeDelegate:delegate]; } - (void)removeAllDelegates { [_multicastDelggate removeAllDelegates]; }
其他的用法和普通的delegate类似
// 协议 @protocol InAppPurchasesServiceProtocol <NSObject> @optional /** * @brief callback for update product list succeed */ -(void)inAppPurchasesService:(InAppPurchasesService *)service didUpdatedProducts:(NSArray *)array; // 用的时候 [self.multicastDelggate inAppPurchasesService:self didUpdatedProductsFailed:error];
本文建议结合上篇博文一起学习: 【IOS 开发学习总结-OC-20】★★★objective-c面向对象——协议(protocol)
参考资料:
1./article/1822252.html
2.http://www.jianshu.com/p/b6434c2997d1
3.http://leopard168.blog.163.com/blog/static4./168471844201306114533858/
4.https://github.com/robbiehanson/XMPPFramework
相关文章推荐
- Objective C中nil/Nil/NULL的区别
- 封装的概念和原理,set和get方法
- 类方法
- NSString字符串长度计算方法
- NSString类的介绍和用法
- object-c结构体赋值
- object-c Person类实现和分析
- Object转为String的几种形式
- object-c中对象创建
- object-c中类的声明和实现
- OC中的异常捕捉机制
- NSLog和print使用的差异
- Foundation/Foundation.h 是什么东西?
- #import和#include
- 黑马程序员---Java基础---Object类和String类
- object-c线程延迟执行
- objective-c创建线程的3种方式
- 点击苹果模拟器触发事件
- swift继承自Objective-C基类时重载方法报错的问题
- iOS经典讲解之Objective-C属性的内存管理原理