讀AFNetworking源碼第四次的收穫與思考

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

相關文章
相關標籤/搜索