关于控制器 dealloc 后自动取消网络请求

2018-11-14  本文已影响9人  hotIcecream

必要性:

当某个页面销毁后如果依然存在未结束的网络请求,那么不仅会浪费流量而且会占用一部分内存得不到释放直到请求结束。

时机:

当不需要处理请求返回结果的时候就可以在某个时机来 cancel 掉这些无用的请求,而这个时机就是 dealloc 的时候。

原理:

- (void)addAutoCancelRequestSessionTaskNoti {
    @weakify(self);
    // 接收执行请求的 sessionTask
    [[NSNotificationCenter defaultCenter] addObserverForName:kRequestSessionTaskNotificationName object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        @strongify(self);
        if (!self) return;
        
        NSDictionary *userInfo = note.userInfo;
        if (userInfo == nil || ![userInfo allKeys].count) return;
        
        if (![[userInfo valueForKey:kRequestSessionTaskControllerNameKey] isEqualToString:NSStringFromClass([self class])]) return;
        
        NSURLSessionTask *task = (NSURLSessionTask *)[userInfo valueForKey:kRequestSessionTaskKey];
        [self addAutoCancelSessionTask:task];
    }];
    
    // 接收执行的请求成功/失败的 sessionTask
    [[NSNotificationCenter defaultCenter] addObserverForName:kAutoCancelSessionTaskNotificationName object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        @strongify(self);
        if (!self) return;
        
        NSDictionary *userInfo = note.userInfo;
        if (userInfo == nil || ![userInfo allKeys].count) return;
        
        if (![[userInfo valueForKey:kRequestSessionTaskControllerNameKey] isEqualToString:NSStringFromClass([self class])]) return;
        
        NSURLSessionTask *task = (NSURLSessionTask *)[userInfo valueForKey:kRequestSessionTaskKey];
        [self removeAutoCancelSessionTask:task];
    }];
}
/// 取消当前页所有未完成请求
- (void)autoCancelCurrentRequestTasks {
    if (!self.autoCancelSessionTasks.count) return;
    
    [NETWORK cancelRequestWithTasks:[[NSArray alloc] initWithArray:self.autoCancelSessionTasks copyItems:YES]];
    
    [self.autoCancelSessionTasks removeAllObjects];
}
/// 通过堆栈信息获取网络请求控制器
- (UIViewController *)searchNetworkRequestVc {
    NSArray<NSString *> *stackSymbols = [NSThread callStackSymbols];

    for (NSString *symbol in stackSymbols) {
        NSArray<NSString *> *array = [symbol componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"[]"]];
        if (array.count < 2) continue;
        
        NSString *selString = array[1];
        if (selString.length) {
            NSArray *tempArr = [selString componentsSeparatedByString:@" "];
            if (tempArr[0]) {
                Class c = NSClassFromString(tempArr[0]);
                if ([c isSubclassOfClass:[UIViewController class]]) {
                    return (UIViewController *)c;
                }
            }
        }
    }
    return nil;
}

不足:

参考链接:

https://www.jianshu.com/p/20f6172524d6

第三方:

最后附上

上一篇 下一篇

猜你喜欢

热点阅读