读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?

相关文章
相关标签/搜索