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. */
請求的默認超時。如果給定的超時值沒有傳輸數(shù)據(jù),這將導致超時,并且在傳輸數(shù)據(jù)時重置。

@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.
*/
設置接收器的超時間隔。
超時間隔指定加載過程中分配給請求的空閑間隔的限制?!翱臻e時間間隔”是指自上一個加載活動實例發(fā)生在正在加載的請求之后經過的時間段。因此,當發(fā)生加載活動的實例(例如,從網絡接收請求的字節(jié))時,請求的空閑時間間隔將重置為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;
}

核心的測試函數(shù)

- (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優(yōu)先級比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

根據(jù)測試2個值的結論和這里的輸出結果可以得知:如果設置了3個值,那么超時時間是timeoutResourcetimeout中的較小值

結論

  1. 設置了NSURLRequest timeoutInterval
    忽略timeoutIntervalForRequest設置,超時時間是timeoutIntervalForResource、timeoutInterval較小的值。
  2. 沒有設置NSURLRequest timeoutInterval
    超時時間是timeoutIntervalForRequest、timeoutIntervalForResource較小的值。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容