Swift学习日记(3) --关于请求多个接口导致UI绘制顺序不正确及GCD

这篇具有很好参考价值的文章主要介绍了Swift学习日记(3) --关于请求多个接口导致UI绘制顺序不正确及GCD。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

调用多个接口然后刷新列表导致加载顺序不正确

问题描述:在我写的controller里面 需要去请求三个接口:广告接口 九宫格接口 单曲接口

每个接口对应的是tableview里面每一个cell的数据,为了图省事,我把三个接口直接扔在viewdidload里面,然后在每个接口请求完数据之后刷新一下列表。
代码如下:

    override func viewDidLoad() {
        super.viewDidLoad()

        fetchDataAndUpdateUI()
        
    }

这个 fetchDataAndUpdateUI()是广告接口
在这个广告接口里面代码如下:

func fetchDataAndUpdateUI() {
        let position = 0
        let target:DefaultService = .ads(position: position)
        
        let cancellable = NetWorkManage.request(target, completion: { responseDict in
            // 解析成功的响应
            if let nestedData = responseDict["data"] as? [String: Any],
               let dataArray = nestedData["data"] as? [[String: Any]] {
                var ads = [Ad]()
                for adData in dataArray {
                    if let ad = Ad.deserialize(from: adData) {
                        ads.append(ad)
                    } else {
                        print("Failed to parse ad data.")
                    }
                }

                let bannerData = BannerData(ads)
                self.datum.removeAll()
                self.datum.append(bannerData)
                self.datum.append(ButtonData())
                self.sheets()
                
            } else {
                print("Nested data field not found in JSON or has incorrect format.")
            }
        }, fail: { networkError in
            // 处理请求失败的情况
            print("Network request failed with code: \(networkError.code ?? "") and message: \(networkError.message ?? "")")
        })
    }

重点是 self.sheets()在这里我调用了第二个九宫格数据接口,原来的话我是直接reloadData()刷新一下列表。
然后接着来看Sheets()这个接口
代码如下:

func sheets() {
        let size = 12
        let target:DefaultService = .sheets(size: size)
        
        let cancellable = NetWorkManage.request(target, completion: { responseDict in
            // 解析成功的响应
            if let nestedData = responseDict["data"] as? [String: Any],
               let dataArray = nestedData["data"] as? [[String: Any]] {
                var sheets = [Sheet]()
                for adData in dataArray {
                    if let sheet = Sheet.deserialize(from: adData) {
                        sheets.append(sheet)
                    } else {
                        print("Failed to parse ad data.")
                    }
                }
                
                self.datum.append(SheetData(sheets))
                self.loadSong()
            } else {
                print("Nested data field not found in JSON or has incorrect format.")
            }
        }, fail: { networkError in
            // 处理请求失败的情况
            print("Network request failed with code: \(networkError.code ?? "") and message: \(networkError.message ?? "")")
        })
    }

同样的 这里的重点是 请求了一下self.loadSong()请求了一下单曲数据
最后再来看一下loadSong里面的代码

func loadSong(){
        let size = 12
        let target:DefaultService = .songs
        
        let cancellable = NetWorkManage.request(target, completion: { responseDict in
            // 解析成功的响应
            if let nestedData = responseDict["data"] as? [String: Any],
               let dataArray = nestedData["data"] as? [[String: Any]] {
                var songs = [Song]()
                for adData in dataArray {
                    if let song = Song.deserialize(from: adData) {
                        songs.append(song)
                    } else {
                        print("Failed to parse ad data.")
                    }
                }
            
                self.datum.append(SongData(songs))
                self.tableView.reloadData()
            } else {
                print("Nested data field not found in JSON or has incorrect format.")
            }
        }, fail: { networkError in
            // 处理请求失败的情况
            print("Network request failed with code: \(networkError.code ?? "") and message: \(networkError.message ?? "")")
        })
    }

请求完loadSong之后 我才调用self.tableView.reloadData()来刷新整个tableview
这样嵌套的话就不会出现cell绘制的过程中顺序错误。

当然其实这只能说是最低端的写法,只是给初学者进行参考(ps:我也是),但是查阅资料学习的过程中发现了问题。

其实优化一下的话是要用gcd来进行并发处理请求回来这三个数据之后再去reloadData()刷新列表,但我还没用上。

我问的GPT代码贴到下方:

class DiscoveryController: UIViewController {

    // ... 省略了其他代码

    override func viewDidLoad() {
        super.viewDidLoad()
        // ... 省略了其他代码
        fetchDataAndUpdateUI()
    }

    func fetchDataAndUpdateUI() {
        let group = DispatchGroup()

        group.enter()
        fetchAdsData(group: group)

        group.enter()
        fetchSheetsData(group: group)

        group.notify(queue: .main) {
            self.tableView.reloadData()
        }
    }

    func fetchAdsData(group: DispatchGroup) {
        // ... 省略了网络请求的代码,保持和之前一样的逻辑
        // 记得在请求完成或失败后调用 group.leave()
    }

    func fetchSheetsData(group: DispatchGroup) {
        // ... 省略了网络请求的代码,保持和之前一样的逻辑
        // 记得在请求完成或失败后调用 group.leave()
    }

    // ... 省略了其他代码

}

这里就是等待三个接口都请求回来数据然后再进行刷新
当然肯定不止这种方法,如果可以的话希望多多给我这个菜鸟意见我会认真学习。

那我写的方法和这个gcd的区别是什么呢,是耗时问题,这里不再多说。一层层依赖的请求一个之后再请求另外一个接口的耗时肯定是要比并发用GCD方式耗时要长。

其实当我修改完正确代码我并不清楚问题发生的原因,然后我去问GPT
给我的回答如下

这个问题可能源自于多个网络请求导致的数据加载和刷新问题。当每个接口请求数据并且刷新 tableView 时,数据的加载顺序和速度可能会有所不同,从而导致显示混乱。

在你最初的方法中,每个接口请求都会触发 tableView.reloadData(),这意味着每个接口完成都会导致整个表格刷新。如果这些网络请求的完成顺序与你期望的不一致,就会导致 UI 上的显示问题,出现数据错乱或九宫格和单曲数据交错显示的情况。

使用 GCD 或者串行请求的方式可以确保你按照正确的顺序获取和处理数据,然后在所有数据都准备好后再一次性刷新 tableView。这样可以避免多个接口请求导致的显示混乱问题。

另外,也可以检查数据模型的赋值和对应的 UI 绑定是否正确。确保每个数据源和对应的 cell 显示的数据是匹配的,避免数据源出现错位或重叠的情况。

最重要的是要确保在刷新 tableView 之前,数据已经完全准备好,否则可能导致显示上的混乱。

以上是本节内容,希望有错误大佬们指正。文章来源地址https://www.toymoban.com/news/detail-771269.html

到了这里,关于Swift学习日记(3) --关于请求多个接口导致UI绘制顺序不正确及GCD的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python+unittest+requests+HTMLRunner搭建接口测试框架,执行用例请求多个不同请求方式的接口

    问题描述: 搭建接口测试框架,执行用例请求多个不同请求方式的接口 实现步骤: ① 创建配置文件config.ini,写入部分公用参数,如接口的基本url、测试报告文件路径、测试数据文件路径等配置项 ② 从配置文件中读取并返回文件中内容,或写入配置文件的方法,文件命名

    2024年02月15日
    浏览(46)
  • 关于使用 Element UI 的 el-image 组件导致本地图片不显示的问题

    当使用 el-image /el-image 在网页中加载本地图片时,会出现图片加载失败的问题,但使用 img / 标签可以正常显示。 在 element 组件上使用相对路径时 webpack 不会对路径进行处理,导致请求了一个无效的路径。 将 el-image src=\\\"../assets/bg_login.jpeg\\\"/el-image 改为 el-image :src=\\\"require(\\\'../asset

    2024年02月06日
    浏览(48)
  • 项目引入多个连接池,导致使用其他连接池,maven分析学习

    第一步在命令行中执行 如果你的settings文件不是项目使用的setting配置,那么就使用下面的命令 然后打开这个输出的 excludeParentstart.log文件 然后得到了一堆密密麻麻的文件 这个玩意怎么看呢?我们得先知道依赖加载顺序 执行命令 mvn dependency:tree 会输出Maven项目的依赖树,展示

    2024年02月11日
    浏览(40)
  • Ruoyi-Vue处理跨域问题、同时请求多个域名接口(前端处理)

    Ruoyi-Vue项目请求不同地址的接口,主要在于处理跨域问题,即vue.config.js文件处理 1. 修改配置文件(.env.development/.env.production) 2. 修改vue.config.js文件 即新增一个代理。部署项目时, 如果使用nginx等代理方式,记得配置VUE_APP_API_SERVICE对应的路径及跳转地址 3. 新建requestNew.js文件

    2024年02月03日
    浏览(41)
  • vue中使用element-ui,重复点击按钮或多个请求同时报错时弹出多个message弹框解决方法

    1. 用这种 2. 参考: vue中使用element-ui,重复点击按钮或多个请求同时报错时弹出多个message弹框解决方法_donggua_123的博客-CSDN博客

    2024年02月11日
    浏览(49)
  • 接口测试-关于postman的几种参数请求方式

    (1)POST的数据类型 对于post请求方式,一般都是要对请求发送相应的一些参数的,而参数的注入一般填写在Body中。  如上图所示,在Body中,有多种类型选择: none:一般都不使用 form-data:  对于form-data,是采用键值对的方式进行存储,即将该表单的数据组织成Key-Value形式,

    2024年02月12日
    浏览(84)
  • 关于Postman通过cookie请求接口的注意事项

    问题: 没有cookie信息时,直接用Postman访问接口会报401错误:   解决方案: 在浏览器上方获取cookie信息,填入到postman中。 一、首先点击浏览器上方地址栏旁边找到cookie: 二、然后找到对应地址的jwt信息,将里面的几个value给拷贝出来: 三、在Postman上添加cookie信息: 点击

    2024年02月11日
    浏览(47)
  • Spring Boot框架中Controller层API接口如何支持使用多个@RequestBody注解接受请求体参数

    众所周知,在Spring Boot框架中,Controller层API接口编码获取请求体参数时,在参数上会使用@RequestBody注解;如果一次请求中,请求体参数携带的内容需要用多个参数接收时,能不能多次使用@RequestBody注解呢? 下面我们先测试一下,参考代码: PostMan进行请求: 服务端后端日志:

    2024年01月17日
    浏览(55)
  • Element UI 实现Upload多文件上传 (只请求一次接口)

    ** ** ** ** 注: 页面上用到的请求 是封装好的 from-data 表单提交后台 效果图展示: 请求参数展示: 后端代码springboot代码展示:

    2024年02月16日
    浏览(36)
  • 关于Springboot集成swagger2出现的swagger-resouces和ui请求的404问题

    本项目集成的是增强版的Swagger文档,使用的增强版的UI com.github.xiaoymin 按照上面的配置,在本地测试效果是正常的 在红色标记的地方是正常显示的,但是按照这个配置打war包部署到服务器或者本地的tomcat中就会出现404的现象。 出现上面的这种情况时,看过很多网上的帖子说

    2024年04月17日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包