『ios』论ios网络请求缓存sessionTask的重要性。
2018-10-09 本文已影响14人
butterflyer
开门见山,先看问题。
QQ20181009-142847-HD.gif QQ20181009-142911-HD.gif
上面是最近碰到的一个问题,注意看两个gif图,如果很慢的删除textfield里的字母,是正常显示,如果很快的删除,那么在当全删除完的时候,还会有最后一个网络请求正在进行中,所以现在我们要解决这个问题,那就要用到缓存sessiontask了。
首先要在我们用的数据请求工具类里,创建一个用来缓存allSessionTask.
static NSMutableArray *_allSessionTask;
+ (NSMutableArray *)allSessionTask {
if (!_allSessionTask) {
_allSessionTask = [[NSMutableArray alloc] init];
}
return _allSessionTask;
}
第二步当然就是每个请求都添加到这个里面。
+ (NSURLSessionTask *)POST:(NSString *)URL
parameters:(id)parameters
responseCache:(PPHttpRequestCache)responseCache
success:(PPHttpRequestSuccess)success
failure:(PPHttpRequestFailed)failure {
//读取缓存
responseCache!=nil ? responseCache([PPNetworkCache httpCacheForURL:URL parameters:parameters]) : nil;
//加密 header body
[self encodeParameters:parameters];
NSURLSessionTask *sessionTask = [_sessionManager POST:URL parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (_isOpenLog) {PPLog(@"responseObject = %@",[self jsonToString:responseObject]);}
[[self allSessionTask] removeObject:task];
NSInteger statusCode = [(NSHTTPURLResponse *)[task response] statusCode];
if(statusCode == 200){//只要不是200就走下面
success ? success(responseObject) : nil;
//对数据进行异步缓存
responseCache!=nil ? [PPNetworkCache setHttpCache:responseObject URL:URL parameters:parameters] : nil;
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (_isOpenLog) {PPLog(@"error = %@",error);}
[[self allSessionTask] removeObject:task];
failure ? failure(error) : nil;
NSInteger statusCode = [(NSHTTPURLResponse *)[task response] statusCode];
if(statusCode == 401){
DLog(@"签名错误");
}
}];
// 添加最新的sessionTask到数组 这里才是重点
sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil ;
return sessionTask;
}
上面是添加,下面就到了清空sessionTask缓存
NSURLSession里面属于NSURLSessionTask的对象cancel方法。
image.png
+ (void)cancelAllRequest {
// 锁操作
@synchronized(self) {
[[self allSessionTask] enumerateObjectsUsingBlock:^(NSURLSessionTask *_Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
[task cancel];
}];
[[self allSessionTask] removeAllObjects];
}
}
+ (void)cancelRequestWithURL:(NSString *)URL {
if (!URL) { return; }
@synchronized (self) {
[[self allSessionTask] enumerateObjectsUsingBlock:^(NSURLSessionTask *_Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
if ([task.currentRequest.URL.absoluteString hasPrefix:URL]) {
[task cancel];
[[self allSessionTask] removeObject:task];
*stop = YES;
}
}];
}
}
讲完这些,该回到之前的问题上,如何解决问题。我们要做的就是在删除完最后一个字母的时候,清空所有的seesionTask。