AFN中timeoutIntervalForRequest,timeoutIntervalForResource,timeoutInterval测试总结

NSURLSessionConfiguration

/* default timeout for requests. This will cause a timeout if no data is transmitted for the given timeout value, and is reset whenever data is transmitted. */
请求的默认超时。如果给定的超时值没有传输数据,这将导致超时,并且在传输数据时重置。

@property NSTimeInterval timeoutIntervalForRequest;

/* default timeout for requests. This will cause a timeout if a resource is not able to be retrieved within a given timeout. */
请求的默认超时。如果在给定的超时内无法检索资源,这将导致超时。

@property NSTimeInterval timeoutIntervalForResource;

NSMutableURLRequest

/*!
@abstract Sets the timeout interval of the receiver.
@discussion The timeout interval specifies the limit on the idle
interval allotted to a request in the process of loading. The "idle
interval" is defined as the period of time that has passed since the
last instance of load activity occurred for a request that is in the
process of loading. Hence, when an instance of load activity occurs
(e.g. bytes are received from the network for a request), the idle
interval for a request is reset to 0. If the idle interval ever
becomes greater than or equal to the timeout interval, the request
is considered to have timed out. This timeout interval is measured
in seconds.
*/
设置接收器的超时间隔。
超时间隔指定加载过程中分配给请求的空闲间隔的限制。“空闲时间间隔”是指自上一个加载活动实例发生在正在加载的请求之后经过的时间段。因此,当发生加载活动的实例(例如,从网络接收请求的字节)时,请求的空闲时间间隔将重置为0。如果空闲时间间隔大于或等于超时时间间隔,则认为请求已超时。此超时间隔以秒为单位。

@property NSTimeInterval timeoutInterval;

注:

  1. AFN中设置manager.requestSerializer.timeoutInterval = timeoutInterval;最终会设置到mutableURLRequest.timeoutInterval = timeoutInterval
NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.google.com"]];
 NSLog(@"%.2f", mutableRequest.timeoutInterval);

这个默认的是60秒

  1. 下述的例子是用charles把http://www.baidu.com设置为breakpoint了(超时设置)

设计一个单例

@interface RXTimeoutIntervalManager()
@property (nonatomic, strong) NSMutableArray *managerArray;
@end

- (void)addManager:(id)manager {
    @synchronized (self.managerArray) {
        [self.managerArray addObject:manager];
    }
}
- (void)removeManager:(id)manager {
    @synchronized (self.managerArray) {
        [self.managerArray removeObject:manager];
    }
}

- (id)init {
    if (self = [super init]) {
        self.managerArray = [NSMutableArray new];
    }
    return self;
}
- (void)printWithStartTime:(CFAbsoluteTime)startTime mutDic:(NSMutableDictionary *)mutDic {
    CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent();
    CFAbsoluteTime time = endTime - startTime;
    mutDic[@"cost"] = [NSString stringWithFormat:@"%.5f", time];
    NSMutableArray *ary = [NSMutableArray new];
    // 手动按照这个顺序输出
    NSArray *keyArray = @[@"cost", @"timeoutRequest", @"timeoutResource", @"timeout"];
    for (NSString *key in keyArray) {
        [ary addObject:[NSString stringWithFormat:@"%@=%@", key, mutDic[key]]];
    }
    printf("%s\n", [[ary componentsJoinedByString:@","] UTF8String]);
}
+ (instancetype)sharedInstance
{
    static id sharedInstance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

核心的测试函数

- (void)_test_timeoutRequest:(NSTimeInterval)timeoutRequest timeoutResource:(NSTimeInterval)timeoutResource timeout:(NSTimeInterval)timeout {
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    if (timeoutRequest > 0) {
        config.timeoutIntervalForRequest = timeoutRequest;
    }
    if (timeoutResource > 0) {
        config.timeoutIntervalForResource = timeoutResource;
    }
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:config];
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    if (timeout > 0) {
        manager.requestSerializer.timeoutInterval = timeout;
    }
    [self addManager:manager];
    NSMutableDictionary *mutDic = [NSMutableDictionary new];
    mutDic[@"timeoutRequest"] = @(timeoutRequest);
    mutDic[@"timeoutResource"] = @(timeoutResource);
    mutDic[@"timeout"] = @(timeout);
    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
    __weak typeof(self) weakSelf = self;
    [manager GET:@"http://www.baidu.com" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [weakSelf printWithStartTime:startTime mutDic:mutDic];
        [weakSelf removeManager:manager];
     } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
         [weakSelf printWithStartTime:startTime mutDic:mutDic];
         [weakSelf removeManager:manager];
         NSLog(@"error:%@", error);
     }];
}

测试不设置任何值的时候

- (void)_test_zero {
    [self _test_timeoutRequest:0 timeoutResource:0 timeout:0];
}
cost=60.02540,timeoutRequest=0,timeoutResource=0,timeout=0

如果没有设置任何值那么超时时间是60秒

测试1个值

- (void)_test_one {
    [self _test_timeoutRequest:3 timeoutResource:0 timeout:0];
    [self _test_timeoutRequest:0 timeoutResource:3 timeout:0];
    [self _test_timeoutRequest:0 timeoutResource:0 timeout:3];
}
cost=3.15270,timeoutRequest=0,timeoutResource=3,timeout=0
cost=3.17170,timeoutRequest=3,timeoutResource=0,timeout=0
cost=3.15597,timeoutRequest=0,timeoutResource=0,timeout=3

很明显,那唯一的一个值起作用

测试2个值

- (void)_test_two {
    [self _test_timeoutRequest:3 timeoutResource:6 timeout:0];
    [self _test_timeoutRequest:6 timeoutResource:3 timeout:0];
    [self _test_timeoutRequest:0 timeoutResource:3 timeout:6];
    [self _test_timeoutRequest:0 timeoutResource:6 timeout:3];
    [self _test_timeoutRequest:3 timeoutResource:0 timeout:6];
    [self _test_timeoutRequest:6 timeoutResource:0 timeout:3];
}
1. cost=3.00128,timeoutRequest=6,timeoutResource=3,timeout=0
2. cost=3.01349,timeoutRequest=0,timeoutResource=3,timeout=6
3. cost=3.01761,timeoutRequest=0,timeoutResource=6,timeout=3
4. cost=3.01677,timeoutRequest=6,timeoutResource=0,timeout=3
5. cost=3.03217,timeoutRequest=3,timeoutResource=6,timeout=0
6. cost=6.01479,timeoutRequest=3,timeoutResource=0,timeout=6

结果1与结果5可知,如果只设置了timeoutRequesttimeoutResource,那么取最小值
结果2与结果3可知,如果只设置了timeoutResourcetimeout,那么取最小值
结果4与结果6可知,如果只设置了timeoutRequesttimeout那么只取timeout,也就是说timeout优先级比timeoutRequest

测试3个值

- (void)_test_three {
    [self _test_timeoutRequest:3 timeoutResource:6 timeout:9];
    [self _test_timeoutRequest:3 timeoutResource:9 timeout:6];
    [self _test_timeoutRequest:6 timeoutResource:3 timeout:9];
    [self _test_timeoutRequest:6 timeoutResource:9 timeout:3];
    [self _test_timeoutRequest:9 timeoutResource:3 timeout:6];
    [self _test_timeoutRequest:9 timeoutResource:6 timeout:3];
}
cost=3.00077,timeoutRequest=9,timeoutResource=3,timeout=6
cost=3.00263,timeoutRequest=6,timeoutResource=3,timeout=9
cost=3.03130,timeoutRequest=6,timeoutResource=9,timeout=3
cost=3.02951,timeoutRequest=9,timeoutResource=6,timeout=3
cost=6.02499,timeoutRequest=3,timeoutResource=6,timeout=9
cost=6.05182,timeoutRequest=3,timeoutResource=9,timeout=6

根据测试2个值的结论和这里的输出结果可以得知:如果设置了3个值,那么超时时间是timeoutResourcetimeout中的较小值

结论

  1. 设置了NSURLRequest timeoutInterval
    忽略timeoutIntervalForRequest设置,超时时间是timeoutIntervalForResourcetimeoutInterval较小的值。
  2. 没有设置NSURLRequest timeoutInterval
    超时时间是timeoutIntervalForRequesttimeoutIntervalForResource较小的值。

你可能感兴趣的:(AFN中timeoutIntervalForRequest,timeoutIntervalForResource,timeoutInterval测试总结)