写高质量OC代码52建议总结:39.用handler块降低代码分散程度
来源:互联网 发布:淘宝云客服判断题 编辑:程序博客网 时间:2024/06/11 18:27
iOS系统上有个“系统监控器”,如果程序在一定时间内无响应,就会被自动终止。所以,在处理用户界面的显示及触摸操作所用的线程(主线程)不能因为要执行I/O或者网络通信这类耗时的任务而阻塞。
异步方法在执行完任务后,需要以某种手段通知相关代码。常用的手段是设计委托代理。当相关事件发生时就可以通知对象执行相关操作了。
#import <Foundation/Foundation.h>@class EOCNetworkFercher;@protocol EOCNetworkFetcherDelegate <NSObject>-(void)networkFetcher:(EOCNetworkFercher *)networkFetcher didFinishWithData:(NSDate *)data;@end@interface EOCNetworkFercher : NSObject@property (nonatomic, weak) id <EOCNetworkFetcherDelegate>delegate;-(id)initWithUrl:(NSURL *)url;-(void)start;@end其他类可以使用此类的API
-(void)fetchFooData { NSURL *url = [[NSURL alloc] initWithString:@"http://www.example.com/foo.dat"]; EOCNetworkFercher *fetcher = [[EOCNetworkFercher alloc] initWithUrl:url]; fetcher.delegate = self; [fetcher start];}-(void)networkFetcher:(EOCNetworkFercher *)networkFetcher didFinishWithData:(NSDate *)data{ // get data}如果用块来改写的话,代码会更加清晰,开发者调用更加方便。
#import <Foundation/Foundation.h>@class EOCNetworkFercher;@protocol EOCNetworkFetcherDelegate <NSObject>-(void)networkFetcher:(EOCNetworkFercher *)networkFetcher didFinishWithData:(NSDate *)data;@endtypedef void (^EOCNetworkFetcherCompletionHandler)(NSData *data);@interface EOCNetworkFercher : NSObject@property (nonatomic, weak) id <EOCNetworkFetcherDelegate>delegate;-(id)initWithUrl:(NSURL *)url;-(void)start;-(void)startWithCompletionHandler:(EOCNetworkFetcherCompletionHandler)handler;@end这和委托协议很像,不过多了个好处,在调用start方法时可以以内联形式定义completion handler。
-(void)fetchFooDataTwo { NSURL *url = [[NSURL alloc] initWithString:@"http://www.example.com/foo.dat"]; EOCNetworkFercher *fetcher = [[EOCNetworkFercher alloc] initWithUrl:url]; [fetcher startWithCompletionHandler:^(NSData *data) { // get data }];}委托模式有两个缺点,如果类要使用多个获取器下载不同数据。就需要在代理方法中判断获取器的类型以处理不同的数据。
-(void)networkFetcher:(EOCNetworkFercher *)networkFetcher didFinishWithData:(NSDate *)data{ if (networkFetcher == /*....*/) { // data.... } else if (networkFetcher == /*....*/) { // data.... }}这么写代码不稳定性很高,而且会很快使代码量激增。改用块来处理的好处是:无需监听获取器,也无需在监听方法中判断获取器。
-(void)fetchFooDataThree { NSURL *url = [[NSURL alloc] initWithString:@"http://www.example.com/foo.dat"]; EOCNetworkFercher *fetcher = [[EOCNetworkFercher alloc] initWithUrl:url]; [fetcher startWithCompletionHandler:^(NSData *data) { // get data }]; NSURL *urlTwo = [[NSURL alloc] initWithString:@"http://www.example.com/foo.dat"]; EOCNetworkFercher *fetcherTwo = [[EOCNetworkFercher alloc] initWithUrl:urlTwo]; [fetcherTwo startWithCompletionHandler:^(NSData *data) { // get data }];}这种写法还有别的用处,现在很多基于块的API被用来处理错误。可以用两个块来分别处理成功和失败两种情况。也可以把成功和失败的处理都放在一个块中。
typedef void (^EOCNetworkFetcherCompletionHandler)(NSData *data);typedef void(^EOCNetworkFetcherErrorHandler)(NSError *error);@interface EOCNetworkFercher : NSObject@property (nonatomic, weak) id <EOCNetworkFetcherDelegate>delegate;-(id)initWithUrl:(NSURL *)url;-(void)start;-(void)startWithCompletionHandler:(EOCNetworkFetcherCompletionHandler)handler;-(void)startWithCompletionHandler:(EOCNetworkFetcherCompletionHandler)handler failureHandler:(EOCNetworkFetcherErrorHandler)failHandler;@end
-(void)fetchFooDataFour { NSURL *url = [[NSURL alloc] initWithString:@"http://www.example.com/foo.dat"]; EOCNetworkFercher *fetcher = [[EOCNetworkFercher alloc] initWithUrl:url]; [fetcher startWithCompletionHandler:^(NSData *data) { // get data } failureHandler:^(NSError *error) { // get error }];}总结:
1.在使用对象时,可以使用内联的handler块将相关业务逻辑一起声明。
2.在有多个对象需要监控时,代理模式的实现中需要判断对象。用块实现,可以直接将块与关联对象链接。
3.设计API时可以增加一个参数,调用者通过该参数来决定应该把块安排在那个队列上执行。
阅读全文
0 0
- 写高质量OC代码52建议总结:39.用handler块降低代码分散程度
- 写高质量OC代码52建议总结:34.以“自动释放池块”降低内存峰值
- 写高质量OC代码52建议总结:48.多用块枚举,少用for循环
- 写高质量OC代码52建议总结:37.理解“块”
- 写高质量OC代码52建议总结:38.为常用的块创建typedef
- 写高质量OC代码52建议总结:40.用块引用其所属对象不要出现保留环
- 写高质量OC代码52建议总结:35.用僵尸对象调试内存管理问题
- 写高质量OC代码52建议总结:41.多用派发列队,少用同步锁
- 写高质量OC代码52建议总结:42.多用GCD,少用performSelector系列方法
- 写高质量OC代码52建议总结:28.通过协议提供匿名对象
- 写高质量OC代码52建议总结:30.以ARC简化引用计数
- 写高质量OC代码52建议总结:33.以弱引用避免保留环
- 写高质量OC代码52建议总结:36.不要使用retainCount
- 写高质量OC代码52建议总结:46.不要使用dispatch_get_current_queue
- 写高质量OC代码52建议总结:47.熟悉系统架构
- 写高质量OC代码52建议总结:51.load和initialize
- 写高质量OC代码52建议总结:52.NSTimer会保留其目标对象
- 编写高质量OC代码52建议总结:24.将类的实现代码分散到便于管理的数个分类中
- java将属性设置为私有,在给其添加get/set方法和直接把属性设置成public有什么区别
- Java的历史发展进程
- ubuntu多余内核删除
- Android5.1RJ45驱动移植
- TypeScript介绍
- 写高质量OC代码52建议总结:39.用handler块降低代码分散程度
- iOS Runtime机制原理 寓情于景 情景交融
- C语言之关键字(二)break,continue,volatile,extern以及零值的判断
- 如何选择自动化测试工具
- JavaScript核心概念归纳整理
- sql数据统计——按时间统计
- 剑指offer python语言解法
- 关于Oracle并行处理
- Linux修改系统时间