本文机遇afnetworing2.* 3.0有些修改的地方,本人尚未探究。
首先先上代码,不想探究的可以直接复制粘切去使用了
-(void) getDataFromeNet:(NSString *)urlStr{ NSLog(@"get data from net:%@",urlStr); //请求的url地址 NSURL *url=[NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; //用NSURLRequest包装一下 NSURLRequest *requst = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; //AFHTTPRequestOperation包装一下 AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:requst]; // 调用AFHTTPRequestOperation 的setCompletionBlockWithSuccess方法 [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *op,id responseObject){ NSString *jsonstr=op.responseString; NSData *data=[jsonstr dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSLog(@"NSDictionary%@",dic); dataAarry = [dic objectForKey:@"zdBusinessList"]; // NSLog(@"获取到的数据为:%@",dataAarry); NSLog(@"dataarray connt:%lu",(unsigned long)dataAarry.count); if ([dataAarry count]<1) { UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"没有相关数据" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; [alert show]; }; [self doneLoadingTableViewData]; }failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"发生错误!%@",error); [self doneLoadingTableViewData]; }]; // 最后别忘了start [op start]; }
首先先看这个方法
/*! @method requestWithURL:cachePolicy:timeoutInterval: @abstract Allocates and initializes a NSURLRequest with the given URL and cache policy. @param URL The URL for the request. @param cachePolicy The cache policy for the request. @param timeoutInterval The timeout interval for the request. See the commentary for the <tt>timeoutInterval</tt> for more information on timeout intervals. @result A newly-created and autoreleased NSURLRequest instance. */ + (instancetype)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval;
NSURLRequest类为apple官方的类这个方法上看他的解释,此方法传递三个参数,
URL 不多说了 。
cachePolicy参数是 NSURLReQuestCachePolicy类型的 根缓存有关,感兴趣的可以去探究探究,这里不多说。一般使用NSURLRequestUseProtocolCachePolicy 。
timeoutInteval NSTimeInterval(typedef double NSTimeInterval)类型的 这个参数是为了设置请求超时时间,经常会用到。
然后再看这个方法
从.m文件中查看源码如下
- (instancetype)initWithRequest:(NSURLRequest *)urlRequest { self = [super initWithRequest:urlRequest];//调用一个父类方法 if (!self) { return nil; } self.responseSerializer = [AFHTTPResponseSerializer serializer]; //初始化一个responseSerializer AFHTTPResponseSerializer类型的 return self; }
<span style="font-family: Arial, Helvetica, sans-serif;"> self = [super initWithRequest:urlRequest]</span>
调用父类的方法
现在想在.h中查看其使用说明,发现在.h中并没有这个方法。说明这个方法是重写了父类的方法。我们在去查他的父类发现这个
<span style="font-size:12px;">@interface AFHTTPRequestOperation : AFURLConnectionOperation</span>
<span style="font-size:12px;">@interface AFURLConnectionOperation : NSOperation <NSURLConnectionDelegate, NSURLConnectionDataDelegate, NSSecureCoding, NSCopying></span>
/** Initializes and returns a newly allocated operation object with a url connection configured with the specified url request. This is the designated initializer. @param urlRequest The request object to be used by the operation connection. */ - (instancetype)initWithRequest:(NSURLRequest *)urlRequest NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithRequest:(NSURLRequest *)urlRequest { NSParameterAssert(urlRequest); self = [super init]; if (!self) { return nil; } _state = AFOperationReadyState; self.lock = [[NSRecursiveLock alloc] init];//初始化了一个锁 估计跟进程同步有关 self.lock.name = kAFNetworkingLockName; self.runLoopModes = [NSSet setWithObject:NSRunLoopCommonModes]; self.request = urlRequest; self.shouldUseCredentialStorage = YES; self.securityPolicy = [AFSecurityPolicy defaultPolicy]; return self; }
再看
self.responseSerializer = [AFHTTPResponseSerializer serializer];
+ (instancetype)serializer { return [[self alloc] init]; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.stringEncoding = NSUTF8StringEncoding;//编码方式 self.acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)];//成功的返回码,在这个范围内表示成功会调用成功回调 self.acceptableContentTypes = nil; return self; }
说了这么多其实上面都是一些初始化操作真正主角是下面的方法 他将用于我们请求成功后的处理情况。
- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { // completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-retain-cycles" #pragma clang diagnostic ignored "-Wgnu" self.completionBlock = ^{ if (self.completionGroup) { dispatch_group_enter(self.completionGroup); } dispatch_async(http_request_operation_processing_queue(), ^{ if (self.error) { if (failure) { dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(self, self.error); }); } } else { id responseObject = self.responseObject; if (self.error) { if (failure) { dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(self, self.error); }); } } else { if (success) { dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ success(self, responseObject); }); } } } if (self.completionGroup) { dispatch_group_leave(self.completionGroup); } }); }; #pragma clang diagnostic pop }
具体说下block当中的两个参数
AFHTTPRequestOperation *op,id responseObject
op 也就是我们请求时自己包装的那个 AFHTTPRequestOperration 可以从中获取一些请求信息,常用的是返回码,笔者估计afnetworing中请求成功与否也是通过这里面的请求码来决定的。我们也可以在这里获取请求头信息。
主要的是这里:
NSString *jsonstr=op.responseString; NSData *data=[jsonstr dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
我们中op中获得数据然后自己去解析。
responseObject 这个事服务器给我们返回的数据 可以看到时ID类型的 这个在这里参数我们没有用到。其实这个参数在以后我们用AFHTTPRequestOperationManager的时候回给我们返回成一个解析好的对象,NSArray或者NSDictionnary 我们用起来会很方便,但是在这里笔者曾经打印过发现它并不是一个解析好的对象。我门职能从op中取出结果去自己解析。
最后看下
[op start];
- (void)start { [self.lock lock]; if ([self isCancelled]) { [self performSelector:@selector(cancelConnection) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; } else if ([self isReady]) { self.state = AFOperationExecutingState; [self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; } [self.lock unlock]; }
看看源码还可以了解到这里有iscancellde isReady 不难猜出这里我们可以通过这个op去暂停 或者取消请求。以后在细究吧。