• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 在 dispatch_async 和 dispatch_sysnc 中更新 UI 的区别

[复制链接]
菜鸟教程小白 发表于 2022-12-12 09:44:42 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

假设我有一个名为 session 的 NSURLSession,我想在 downloadTaskWithRequest 中更新我的 UI。现在,情况 1 和情况 2 会发生什么:

案例 1:(dispatch_async)

NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];

NSURLSessionDownloadTask *task= [session downloadTaskWithRequest:request
completionHandler:^(NSURL *localFile, NSURLResponse *response, NSError *error){
    dispatch_async(dispatch_get_main_queue(), ^{
                    // UI Update    
                                               });
}];

案例 2:(使用 dispatch_sync)

NSURLSessionDownloadTask *task= [session downloadTaskWithRequest:request
completionHandler:^(NSURL *localFile, NSURLResponse *response, NSError *error){
    dispatch_sync(dispatch_get_main_queue(), ^{
                    // UI Update    
                                               });
}];



Best Answer-推荐答案


tl;dr 第二种情况将等待 UI 更新完成。首先是更快。

详细

dispathc_sync 阻止当前队列上的执行,直到分派(dispatch)的任务完成。所以,如果主队列上发生了大事,案例二将需要很长时间才能完成。但是,当完成处理程序完成其工作时(例如,如果您在 UI 更新调度后执行某些操作),您确定 UI 已经更新。 此外,如果由于某种未知原因您将配置 session 以在主队列上分派(dispatch)完成 block ,则在第二种情况下您将遇到死锁。这是因为主队列是串行的,这意味着它一次只执行一个任务 - 所以完成处理程序将等待 UI 更新完成,直到完成处理程序没有完成,UI 更新才会开始。

dispatch_async 不会阻塞执行流程。这意味着,您不会以任何方式陷入死锁,并且完成 block 执行时间将不取决于 UI 更新持续时间。但是,即使完成处理程序完成,您也不知道 UI 更新是否完成。 但是,如果您的 completionHandler 分派(dispatch)到主队列,更新的 UI 将仅在 completionHandler 完成后执行。

分割 案例二:

completionHandler:^(NSURL *localFile, NSURLResponse *response, NSError *error){
    //Some code
    //1
    dispatch_sync(dispatch_get_main_queue(), ^{
                    //2
                    // UI Update    
                    //3
                                               });
    //Some code
    //4
}];

到达//1,到达//2,到达//3,到达//4 .保证执行顺序。无论如何——不管是这样还是根本不执行。

案例一:

completionHandler:^(NSURL *localFile, NSURLResponse *response, NSError *error){
    //Some code
    //1
    dispatch_async(dispatch_get_main_queue(), ^{
                    //2
                    // UI Update    
                    //3
                                               });
    //Some code
    //4
}];

到达 //1。保证。在那之后变种可能。 到达 //2,到达 //4,到达 //3。 或者 到达 //4,到达 //2,到达 //3 或者 到达 //2,到达 //3,到达 //4

如果 completionBlock 在主队列上调度,则第二个将始终如此。

如果有什么不清楚的地方欢迎提问

关于ios - 在 dispatch_async 和 dispatch_sysnc 中更新 UI 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33809977/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap