[转]ios的一个架构小例子---异步请求的封装

ios的一个架构小例子---异步请求的封装

分类: ios 764人阅读 评论(5) 收藏 举报

论坛里看到一位兄台的问题:”异步请求能不能封装诚一个公用的类?每个页面都要copy一下几个方法,感觉很麻烦“

可能很多人也会有相同的问题,于是起一篇博客专门谈谈这个问题,主要想阐述一下编程思想及架构设计,权当抛砖引玉。闲话不多说,直接上代码:

MyURLClass.h

  1. #import <Foundation/Foundation.h>  
  2.   
  3.   
  4. @interface MyURLClass : NSObject {  
  5.       
  6. @private  
  7.     NSMutableSet *mDelegates;  
  8.     NSMutableData *mData;  
  9. }  
  10.   
  11. - (void) addDelegate:(id)delegate;  
  12. - (void) removeDelegate:(id)delegate;  
  13.   
  14. @end  


MyURLClass.m

  1. @implementation MyURLClass  
  2.   
  3. - (id)init {  
  4.     [super init];  
  5.     mDelegates = [NSMutableSet new];  
  6.     mData = [NSMutableData new];  
  7.     return self;  
  8. }  
  9.   
  10. - (void) addDelegate:(id)delegate {  
  11.     [mDelegates addObject:delegate];  
  12. }  
  13. - (void) removeDelegate:(id)delegate{  
  14.     [mDelegates removeObject:delegate];  
  15. }  
  16.   
  17. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {  
  18.     [mData appendData:data];  
  19. }  
  20.   
  21. - (void) connectionDidFinishLoading : (NSURLConnection *) connection {  
  22.     NSLog(@"delegate:%@", mDelegates);  
  23.     SEL seltor = @selector(finishWithData:);  
  24.     NSSet * set = [[NSSet alloc] initWithSet:mDelegates];  
  25.     for (id del in set) {  
  26.           
  27.         if ([del respondsToSelector:seltor])  
  28.             [del performSelector:seltor withObject:mData];  
  29.     }  
  30.     [set release];  
  31. }  
  32.   
  33. @end  

至此,我的“异步请求类”就封装好了,mDelegates是用来保存请求对象(即发送异步请求的那个类的对象)的,以便在异步connectionDidFinishLoading的时候调用回调方法,继续:

  1. - (IBAction)sendMyRequest {  
  2.     NSURL *url = [NSURL URLWithString:@"http://www.csdn.net"];  
  3.     NSURLRequest *mRequest = [NSURLRequest requestWithURL:url];  
  4.       
  5.     MyURLClass *urlClass = [[MyURLClass alloc] init];  
  6.     [urlClass addDelegate:self];  
  7.     [[NSURLConnection alloc] initWithRequest:mRequest delegate:urlClass startImmediately:YES];  
  8. }  
  9.   
  10. - (void)finishWithData:(NSData *)data {  
  11.     NSLog(@"%@", data);  
  12.  }  


上面这段代码就是发送请求类的主要一段代码

1、点击按钮后,新建一个MyURLClass类的对象,然后将自己添加到MyURLClass的mDelegates中,之后发送异步请求,并且发送请求的delegate设为MyURLClass的对象

2、请求响应后,就会调用MyURLClass类中的connectionDidFinishLoading方法,在这个方法中会找到发送请求类的 对象,并且调用他的finishWithData方法,同时传递mData这个参数,至此,一个完整的http通信结束,当然不要忘了请求结束把自己从 set中移除(调用removeDelegate:self)

上面的代码只是我写的一个小例子,主要为了体现思想,真正要是封装并且运用到项目中的时候一定要注意:1、在addDelegate和 removeDelegate的时候需要加锁;2、应该先进行数据处理,比如转换为NSDictionary在传递给finishWithData,当 然,不要忘了改finishWithData的参数类型;3、如果你不想所有的回调方法名都叫finishWithData,那你可以做一个关系映射 (struct和NSDictionary都可以满足你的需求),分别存储每个类与回调方法名的对应,同时需要修改SEL seltor = @selector(finishWithData:);这里的实现;4、如果你要写一个封装好的MyURLClass,一定要做成一个全局对象,千万不 要想我上面那样在sendMyRequest中现alloc。

其实能封装的地方还有很多,比如sendMyRequest这个方法就很有被封装的潜力。

简单介绍了一下一个小架构,希望会对大家有所帮助,也欢迎大家讨论。

posted on 2012-05-04 10:23  甲骨魚  阅读(197)  评论(0编辑  收藏  举报

导航