在我的另一篇博客 频繁调用代理方法优化 中我们讲到 使用代理模式。这节我要使用block 来实现同样的效果
但是可以发现 其中的 差别 和 优劣。这两种方式都广泛的应用于 apple 的框架中。
构建类 EOCNetworkFetcher
#import <Foundation/Foundation.h>
typedef void (^EOCNetworkFetcherCompletionHandler)(NSData *data);
@protocol EOCNetworkFetcherDelegate;
@interface EOCNetworkFetcher :NSObject
- (instancetype)initWithURL:(NSURL *)url;
- (void)startWithCompletionHandler:(EOCNetworkFetcherCompletionHandler )handler;
@property (nonatomic,weak)id<EOCNetworkFetcherDelegate>delegate;
- (void)start;
@end
@protocol EOCNetworkFetcherDelegate <NSObject>
- (void)networkFetcher:(EOCNetworkFetcher *)networkFetcher
didFinishedWithData:(NSData *)data;
@end
#pragma mark ---- 使用Block优化
- (void)compare
{
//
EOCNetworkFetcher *fethcer=[[EOCNetworkFetcheralloc]initWithURL:[NSURLURLWithString:@"someUrlString"]];
fethcer.delegate=self;
[fethcer start];
// 一个要在代理方法中返回一个直接在 调用的方法中返回代码更清晰
[fethcer startWithCompletionHandler:^(NSData *data) {
}];
}
- (void)compareTwo
{
// 比如我们有两个 请求两个请求 需要作出不同反应那么我们需要写两个不同全局变量
// 并且在代理方法中也要区别对待 这样导致代码量的激增和 复杂
//
_fooFetcher=[[EOCNetworkFetcheralloc]initWithURL:[NSURLURLWithString:@"fooUrlString"]];
_fooFetcher.delegate=self;
[_fooFetcherstart];
_barFetcher=[[EOCNetworkFetcheralloc]initWithURL:[NSURLURLWithString:@"barUrlString"]];
_barFetcher.delegate=self;
[_barFetcherstart];
// 使用Block不需要 区分
EOCNetworkFetcher *fethcer=[[EOCNetworkFetcheralloc]initWithURL:[NSURLURLWithString:@"fooUrlString"]];
// 一个要在代理方法中返回一个直接在 调用的方法中返回代码更清晰
[fethcer startWithCompletionHandler:^(NSData *data) {
// foo handler
}];
EOCNetworkFetcher *fethcerTwo=[[EOCNetworkFetcheralloc]initWithURL:[NSURLURLWithString:@"barUrlString"]];
[fethcerTwo startWithCompletionHandler:^(NSData *data) {
// bar handler
}];
}
- (void)compareThree
{
// 基于handler 设计代码 还有个原因某些代码必须运行在特定的线程上
// 比如 Cocoa和 Cocoa Touch 中的UI操作必须在主线程上执行
// 因此最好由 API调用者来决定 handler 应该运行在哪个线程上
// 比如 apple 中 NSNotificationCenter中的这个方法
NSOperationQueue *queue=[NSOperationQueuecurrentQueue];
[[NSNotificationCenterdefaultCenter] addObserverForName:@"name"object:nilqueue:queue usingBlock:^(NSNotification *_Nonnull note) {
}];
}
#pragma mark ---- 代理方法
- (void)networkFetcher:(EOCNetworkFetcher *)networkFetcher didFinishedWithData:(NSData *)data
{
//
NSLog(@"fetcher did finish data ");
if (networkFetcher==_barFetcher)
{
//.....
}
elseif (networkFetcher==_fooFetcher){
// .....
}else{
}
}