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;
注:
- AFN中設置
manager.requestSerializer.timeoutInterval = timeoutInterval;最終會設置到mutableURLRequest.timeoutInterval = timeoutIntervalNSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.google.com"]]; NSLog(@"%.2f", mutableRequest.timeoutInterval);這個默認的是60秒
- 下述的例子是用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可知,如果只設置了timeoutRequest和timeoutResource,那么取最小值
結果2與結果3可知,如果只設置了timeoutResource和timeout,那么取最小值
結果4與結果6可知,如果只設置了timeoutRequest和timeout,那么只取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個值,那么超時時間是timeoutResource和timeout中的較小值
結論
- 設置了
NSURLRequest timeoutInterval:
忽略timeoutIntervalForRequest設置,超時時間是timeoutIntervalForResource、timeoutInterval較小的值。- 沒有設置
NSURLRequest timeoutInterval:
超時時間是timeoutIntervalForRequest、timeoutIntervalForResource較小的值。