我们有的时候会借助Block
做延迟操作.如:GCD的dispatch_after
,[UIView animate...] delay
,AFN的网路请求
.当然前两个是人为可控制的,第三个是看网络的心情.
1.GCD dispatch_after
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(20.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self doSomeThingsAct];
});
}
GCD实现延迟是保证Block
存在,到时间再调用.
所以以上代码在延迟期间Block
是持有VC的.如果延迟期间想要VC的销毁,也是不能实现的.
2.AFN的网路请求
- (void)viewDidLoad {
[super viewDidLoad];
AFHTTPSessionManager * mgr = [AFHTTPSessionManager manager];
[mgr GET:url parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, NSData * responseData) {
[self doSomeThingsAct];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
[self doSomeThingsAct2];
}];
}
网络请求实现延迟回调的方式是也保证Block
一直存在,直到网络返回数据,再调用Block
.
所以以上代码在延迟期间Block
是持有VC的.如果延迟期间想要VC的销毁,也是不能实现的.
3.[UIView animate...] delay
- (void)viewDidLoad {
[super viewDidLoad];
[UIView animateWithDuration:2.5 delay:20.0 options:0 animations:^{
[self doSomeThingsAct];
} completion:^(BOOL finished) {
[self doSomeThingsAct2];
}];
}
1.API性质决定对[动画Block]
,先执行,延迟刷新UI;(所以[动画Block]
不用考虑延迟)
2.延迟时间内,VC退出,[完成block]
也会立刻调用+销毁,VC销毁也正常.(API内部有优化)
结论:[UIView animate...]系列方法Block内放心用self,GCD的dispatch_after和AFN的网路请求的用Block还是要注意.
其他系统API,第三方库也用到Block,是否有延迟,是否会因为延迟带来问题,我们得用到时候自己看看.