因爲這個版本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?