使用YTKRequest避免控制器退出后不马上被释放的问题

我们项目中的网络请求基类SomeRequest是封装自YTKRequest的,然后各个API再继承自这个基类,在控制器里面调用API的时候典型是这样写的:

- (void)exeXXXApi{
    xxxApi = [[XXXAPI alloc] initWithXXX];
    [xxxApi startWithCompletionHandlerWithSuccess:^(__kindof ETopBaseRequest *_Nonnull request, id _Nonnull response) {

    }failure:^(__kindof ETopBaseRequest *_Nonnull request, NSInteger code, NSString *_Nonnull errorMsg) {

      }];
}

并没有做任何别的处理。

这样的写法在有些情况下会造成控制器离开后,没有被释放。比如,网络很慢的情况,用户进入一个界面,开始执行一个api请求,然后,等了一会没看到请求数据,就返回退出界面。这时候,控制器的dealloc方法是不会走的,也就是控制器没有在退出后马上被释放,而是被api的success或failure的block引用着,等网络请求完成,调用完这这两个blocks之一后,才会走dealloc方法,释放控制器。这不是我们想要的结果,我们要在控制器退出离开后,就马上释放它。

既然,控制器是被api的blocks引用着才没有马上释放,那么在退出离开时要把这些blocks置为nil,它们就不会引用控制器了,也不会再被api请求完成后执行了。

针对YTKRequest的情况,具体做法分两步:
一,在控制器.m文件里面定义一个属性引用api对象。

@interface SomeController()

@property (nonatomic, strong) SomeRequest *api;

@end

@implimentation SomeController

- (void)exeXXXApi{
    self.api = [[XXXAPI alloc] initWithXXX];
    [self.api startWithCompletionHandlerWithSuccess:^(__kindof ETopBaseRequest *_Nonnull request, id _Nonnull response) {

    }failure:^(__kindof ETopBaseRequest *_Nonnull request, NSInteger code, NSString *_Nonnull errorMsg) {

      }];
}

@end

二,针对返回退出的情况,在控制器的viewWillDisappear方法里面调用YTKRequest的stop方法。

- (void)viewWillDisappear:(BOOL)animated{
    // 导航后退离开界面
    if (![[self.navigationController viewControllers] containsObject: self]) {
        // 离开界面调用这个方法,哪怕api的block与self之间有循环引用,也会释放self
        [self.api stop];
    }
    [super viewWillDisappear:animated];
}

测试证明,以上的写法保证了api无论有没有请求完成,在退出离开控制器时,控制器的dealloc方法都会被执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值