代理-委托模式是Objective-C中一种非常高效的设计模式,这种模式使得我们可以创建一个高复用性的功能型类(用于实现某个单一功能,例如网络数据请求),然后通过协议方法回调返回数据给代理人。这种模式使用了聚合替代了多继承来实现OC类多态的实现。任何类对象都可以遵循多个协议,只要实现相应的协议方法就可以了。
block是一种看起来更像C语言而非OC语言的编程方式,它允许我们使用类似C语言的函数指针将一段代码封装称为对象传递(UIView的动画大多数都使用了block这种特性),同样的在类完成某个功能之后,可以通过调用block方法实现回调的效果。从实现上而言,委托模式跟block的差别看起来并不大,都可以回调函数实现数据交互,都存在着循环引用对象的风险。但是block的使用难度要大于委托,因为我们往往在不经意之间就造成了循环引用,这种错误还非常难发现。同样的,block的功能也要比委托模式更加强大,自动捕捉变量的特性使得block看起来就像玫瑰——美丽但扎手。下面将通过一个简单的demo来演示这两种设计的功能,其中封装网络请求的LXDRequestImage委托类和解析转换网络数据为图像的LXDTransDataToImage类,然后将数据得到的图片显示在viewcontroller中间
图片地址:点击打开链接
LXDRequestImage.h
<span style="font-family:KaiTi_GB2312;font-size:12px;">#import <Foundation/Foundation.h>
@protocol LXDRequestImageDelegate <NSObject>
- (void)finishedRequest: (NSData *)receiveData;
- (void)failedRequest: (NSError *)error;
@end
@interface LXDRequestImage : NSObject
@property (nonatomic, weak) id<LXDRequestImageDelegate> delegate;
- (void)startAnsyRequestWithURL: (NSString *)urlStr;
@end</span>
LXDRequestImage.m
<span style="font-family:KaiTi_GB2312;font-size:12px;">#import "LXDRequestImage.h"
@interface LXDRequestImage ()<NSURLConnectionDelegate, NSURLConnectionDataDelegate>
@end
@implementation LXDRequestImage
{
NSMutableData * receiveData;
}
- (void)startAnsyRequestWithURL: (NSString *)urlStr
{
NSURL * url = [NSURL URLWithString: urlStr];
NSURLRequest * request = [NSURLRequest requestWithURL: url];
NSURLConnection * connection = [NSURLConnection connectionWithRequest: request delegate: self];
if (connection) {
NSLog(@"Success to request");
} else {
NSLog(@"Can not link to network");
}
}
#pragma mark -- NSURLConnectionDelegate
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[self.delegate failedRequest: error];
}
#pragma mark -- NSURLConnectionDataDelegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
receiveData = [NSMutableData data];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[receiveData appendData: data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[self.delegate finishedRequest: receiveData];
}
@end
</span>
LXDTransDataToImage.h
<span style="font-family:KaiTi_GB2312;font-size:12px;">#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface LXDTransDataToImage : NSObject
typedef void(^LXDTransHandler)(UIImage * image);
+ (void)transDataWithData: (NSData *)data transHandler: (LXDTransHandler)transHandler;
@end</span>
LXDTransDataToImage.m
<span style="font-family:KaiTi_GB2312;font-size:12px;">#import "LXDTransDataToImage.h"
@interface LXDTransDataToImage ()
@end
@implementation LXDTransDataToImage
+ (void)transDataWithData:(NSData *)data transHandler:(LXDTransHandler)transHandler
{
transHandler([UIImage imageWithData: data]);
}
@end</span>
附上程序运行图一张: