因为这个版本get请求主要方法在这里:express
AFHTTPOperation *operation = [AFHTTPOperation operationWithRequest:request callback:callback];
接下来咱们来加断点分析一下 AFHTTPOperation 这个类:json
AFHTTPOperation 继承于 QHTTPOperation , QHTTPOperation 继承于 QRunLoopOperation,QRunLoopOperation最后继承与 NSOperation。app
加断点看执行顺序:async
1. + (id)operationWithRequest:(NSURLRequest *)urlRequest callback:(AFHTTPOperationCallback *)callback { return [[[self alloc] initWithRequest:urlRequest callback:callback] autorelease]; } 2. - (id)initWithRequest:(NSURLRequest *)urlRequest callback:(AFHTTPOperationCallback *)callback { self = [super initWithRequest:urlRequest]; if (!self) { return nil; } //可接受的内容类型 self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/plain", nil]; self.callback = callback; return self; } 3. #pragma mark - QRunLoopOperation - (void)operationDidStart { [super operationDidStart]; [[NSNotificationCenter defaultCenter] postNotificationName:AFHTTPOperationDidStartNotification object:self]; } 4. - (void)finishWithError:(NSError *)error { [super finishWithError:error]; NSDictionary *data = nil; if (self.contentTypeAcceptable) { if ([[self.lastResponse MIMEType] isEqualToString:@"application/json"]) { NSError *jsonError = nil; // data = [[JSONDecoder decoder] parseJSONData:self.responseBody error:&jsonError]; data = [NSJSONSerialization JSONObjectWithData:self.responseBody options:kNilOptions error:&jsonError]; } } if (self.statusCodeAcceptable) { [[NSNotificationCenter defaultCenter] postNotificationName:AFHTTPOperationDidSucceedNotification object:self]; if(self.callback.successBlock) { data = [NSJSONSerialization JSONObjectWithData:self.responseBody options:kNilOptions error:nil]; self.callback.successBlock(self.lastRequest, self.lastResponse, data); } } else ...... //这个时候数据已经能够打印出来,回调方法已走: 请求的数据dic:{ code = 0; data = { area = ""; "area_id" = ""; city = "\U5317\U4eac"; "city_id" = 110100; country = "\U4e2d\U56fd"; "country_id" = CN; county = XX; "county_id" = xx; ip = "182.48.105.88"; isp = "\U8054\U901a"; "isp_id" = 100026; region = "\U5317\U4eac"; "region_id" = 110000; }; } 5. - (void)dealloc { [_callback release]; [super dealloc]; }
该类的执行顺序就是这样,ide
可是会涉及到父类,主要看 第三步:oop
#pragma mark * Start and finish overrides - (void)operationDidStart // Called by QRunLoopOperation when the operation starts. This kicks of an // asynchronous NSURLConnection. { assert(self.isActualRunLoopThread); assert(self.state == kQRunLoopOperationStateExecuting); assert(self.defaultResponseSize > 0); assert(self.maximumResponseSize > 0); assert(self.defaultResponseSize <= self.maximumResponseSize); assert(self.request != nil); // If a debug error is set, apply that error rather than running the connection. #if ! defined(NDEBUG) if (self.debugError != nil) { [self finishWithError:self.debugError]; return; } #endif // Create a connection that's scheduled in the required run loop modes. assert(self.connection == nil); self.connection = [[[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO] autorelease]; assert(self.connection != nil); for (NSString * mode in self.actualRunLoopModes) { [self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:mode]; } [self.connection start]; }
@property (retain, readwrite) NSURLConnection * connection;post
NSURLConnection出现了~!~ui
普及知识点: (1) assert 是C里面的宏。用于断言。url
assert的做用是现计算表达式 expression ,若是其值为假(即为0),那么它先向stderr打印一条出错信息,而后经过调用 abort 来终止程序运行。.net
NSAssert 只能在Objective-c里面使用。是assert的一个扩充。能捕获assert类异常及打印一些可读的日志.
(2) NSString *scheme = [URL scheme];// 取出协议头
比较重要的两段代码:
assert(self.connection == nil); self.connection = [[[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO] autorelease]; assert(self.connection != nil); for (NSString * mode in self.actualRunLoopModes) { [self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:mode]; } [self.connection start];
下一篇用旧的 NSURLConnection 作一个 get 请求 体会一下。包括分析一下这里为何要用 runloop?