网络请求实例

网络请求实例切换
背景介绍
这一章来模拟网络请求:在APP中请求网络数据(任务A: 耗时10s),获取数据后进行一定的处理(任务B: 耗时5s),最后刷新UI。

假如A和B都是同步任务,放主队列会死锁,而放其他任何队列,界面都会卡死15s,如果不信,把下面代码里的两种线程休眠方法(二选一,其实不止这两种),放在APP UIViewController里试试:

override func viewDidAppear(_ animated: Bool) {
//1. 全局队列执行同步任务
DispatchQueue.global().sync {
sleep(15)//当前线程休眠15秒
}
//2. 主队列执行异步任务
DispatchQueue.main.async {
sleep(15)//当前线程休眠15秒
}
}
不出所料,两种方法,均让界面卡死15s。回想一下上文说过的:所有的同步任务最终都要安排到主线程运行,主线程运行长耗时任务都会导致界面严重卡顿,所以:

能异步执行的长耗时任务,千万不要同步执行。 长耗时同步任务欠下的债,都由界面来偿还。

假如A和B都是异步任务,即使这样,你也不能都放在主队列中处理,这样也会导致APP界面卡住15s,因为上面说到了:主线程运行长耗时任务都会导致界面严重卡顿。

所有的长耗时任务,千万不要放在主队列中执行。 主队列长耗时异步任务欠下的债,也都由界面来偿还。

说了那么多,你现在应该能够深切地理解各种队列的运行原理了。
现在讲讲使用GCD多线程处理网络请求的正确做法:A、B都定义成异步任务,在并行队列中嵌套异步任务,最后切换到主队列去刷新UI,这样做界面可以保证最流畅。

//创建并行队列,尽量用自定义队列,免得自己的代码质量不过关,影响全局队列
let queue = DispatchQueue(label: “com.apple.request”, attributes: .concurrent)
可以看到队列和线程均进行了预期的切换,GCD队列切换像俄罗斯套娃一样,一层一层的嵌套就行,等嵌套出问题了,去第6章死锁分析寻找原因进行修改即可。
//异步执行
queue.async {

print("开始请求数据 \(Date())  thread: \(Thread.current)")
sleep(10)//模拟网络请求
print("数据请求完成 \(Date())  thread: \(Thread.current)")

//异步执行
queue.async {
    print("开始处理数据 \(Date())  thread: \(Thread.current)")
    sleep(5)//模拟数据处理
    print("数据处理完成 \(Date())  thread: \(Thread.current)")
    
    //切换到主队列,刷新UI
    DispatchQueue.main.async {
        print("UI刷新成功  \(Date())  thread: \(Thread.current)")
    }
}

}

//运行结果
开始请求数据 2020-08-06 06:40:57 +0000 thread: <NSThread: 0x7ff917d8c0c0>{number = 4, name = (null)}
数据请求完成 2020-08-06 06:41:07 +0000 thread: <NSThread: 0x7ff917d8c0c0>{number = 4, name = (null)}
开始处理数据 2020-08-06 06:41:07 +0000 thread: <NSThread: 0x7ff8f7d0c190>{number = 3, name = (null)}
数据处理完成 2020-08-06 06:41:12 +0000 thread: <NSThread: 0x7ff8f7d0c190>{number = 3, name = (null)}
UI刷新成功 2020-08-06 06:41:12 +0000 thread: <NSThread: 0x7ff917c0e7e0>{number = 1, name = main}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值