经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
[iOS]dispatch_after()中self和weakself的使用
来源:cnblogs  作者:EverNight  时间:2021/4/6 10:05:47  对本文有异议
苹果对编译器在不断优化,GCD方法中的block基本都不需要使用weakself,并不会造成循环引用。
dispatch_after官方文档中对block部分的说明:
一:使用self
从ViewControllerA push 到 ViewControllerB。ViewControllerB中代码:
  1. #import "ViewControllerB.h"
  2.  
  3. @interface ViewControllerB ()
  4. @end
  5.  
  6. @implementation ViewControllerB
  7. - (void)viewDidLoad {
  8. [super viewDidLoad];
  9. // Do any additional setup after loading the view.
  10. self.view.backgroundColor = [UIColor blueColor];
  11. }
  12. - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
  13. {
  14. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  15. [self log];
  16. });
  17. [self.navigationController popViewControllerAnimated:YES];
  18. }
  19. - (void)log
  20. {
  21. NSLog(@"Finish");
  22. }
  23. - (void)dealloc
  24. {
  25. NSLog(@"dealloc");
  26. }

输出结果

pop事件后,ViewControllerB关闭,但并没有立刻调用dealloc方法。而是等待倒计时结束后,log方法执行完成,然后再调用dealloc方法。
整个过程不会发生循环引用,在dispatch_after时间结束之前,block强持有self,时间结束后,block被释放,随后ViewControllerB被释放。
 
二:使用weakself
将代码修改为
  1. - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
  2. {
  3. NSLog(@"pop action");
  4. __weak ViewControllerB *weakself = self;
  5. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  6. [weakself log];
  7. });
  8. [self.navigationController popViewControllerAnimated:YES];
  9. }

输出结果

在pop之后,立即调用了dealloc方法,ViewControllerB被释放。不会调用log方法。
 
三:使用weak-strong dance
将代码修改为
  1. - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
  2. {
  3. NSLog(@"pop action");
  4. __weak ViewControllerB *weakself = self;
  5. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  6. __strong ViewControllerB *strongself = weakself;
  7. [strongself log];
  8. });
  9. [self.navigationController popViewControllerAnimated:YES];
  10. }

结果与使用weakself相同。

 

四:结论

1:上述代码中,如果去除[self.navigationController popViewControllerAnimated:YES]操作,三种方法都能够正常完成任务。

2:当block时间内,如果返回上一页面或其他类似操作,导致当前ViewController消失时。

使用self,ViewController会被block强引用,block时间截止完成回调后,释放block,进而释放ViewController。

使用weakself时,不存在强引用,ViewController会被直接销毁。

3:weak-strong dance,在dispatch_after中并没有实际意义。

原文链接:http://www.cnblogs.com/EverNight/p/14608096.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号