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. */
請求的默認(rèn)超時瞳脓。如果給定的超時值沒有傳輸數(shù)據(jù),這將導(dǎo)致超時澈侠,并且在傳輸數(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. */
請求的默認(rèn)超時。如果在給定的超時內(nèi)無法檢索資源哨啃,這將導(dǎo)致超時烧栋。@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.
*/
設(shè)置接收器的超時間隔。
超時間隔指定加載過程中分配給請求的空閑間隔的限制拳球∩笮眨“空閑時間間隔”是指自上一個加載活動實(shí)例發(fā)生在正在加載的請求之后經(jīng)過的時間段。因此祝峻,當(dāng)發(fā)生加載活動的實(shí)例(例如魔吐,從網(wǎng)絡(luò)接收請求的字節(jié))時,請求的空閑時間間隔將重置為0莱找。如果空閑時間間隔大于或等于超時時間間隔酬姆,則認(rèn)為請求已超時。此超時間隔以秒為單位奥溺。@property NSTimeInterval timeoutInterval;
注:
- AFN中設(shè)置
manager.requestSerializer.timeoutInterval = timeoutInterval;
最終會設(shè)置到mutableURLRequest.timeoutInterval = timeoutInterval
NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.google.com"]]; NSLog(@"%.2f", mutableRequest.timeoutInterval);
這個默認(rèn)的是60秒
- 下述的例子是用charles把http://www.baidu.com設(shè)置為breakpoint了(超時設(shè)置)
設(shè)計(jì)一個單例
@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);
}];
}
測試不設(shè)置任何值的時候
- (void)_test_zero {
[self _test_timeoutRequest:0 timeoutResource:0 timeout:0];
}
cost=60.02540,timeoutRequest=0,timeoutResource=0,timeout=0
如果沒有設(shè)置任何值那么超時時間是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
結(jié)果1與結(jié)果5可知,如果只設(shè)置了timeoutRequest
和timeoutResource
浮定,那么取最小值
結(jié)果2與結(jié)果3可知相满,如果只設(shè)置了timeoutResource
和timeout
,那么取最小值
結(jié)果4與結(jié)果6可知桦卒,如果只設(shè)置了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個值的結(jié)論和這里的輸出結(jié)果可以得知:如果設(shè)置了3個值闸盔,那么超時時間是timeoutResource
和timeout
中的較小值
結(jié)論
- 設(shè)置了
NSURLRequest timeoutInterval
:
忽略timeoutIntervalForRequest
設(shè)置悯辙,超時時間是timeoutIntervalForResource
、timeoutInterval
較小的值。- 沒有設(shè)置
NSURLRequest timeoutInterval
:
超時時間是timeoutIntervalForRequest
躲撰、timeoutIntervalForResource
較小的值针贬。