0423 NSRunLoop/多线程
1) 每一个线程都有一个RunLoop
2) 主线程的RunLoop会由系统帮我们启动.
UIScrollView的滚动和下载同时进行,
如果滚动,下载会暂停.
演示:
1. 协议
![](https://app.yinxiang.com/shard/s21/res/c6003e05-2401-41d1-bd03-136225a863d3.png)
2. 实例化scrollView,上面放4个View(不同色)
3. downloadQQ
1) url
2) urlRequest
3) connectionWithRequest
![](https://app.yinxiang.com/shard/s21/res/cb588df3-7035-4c58-9946-99152227fdf5.png)
4) 打印下载长度 // 收到数据的代理方法.
![](https://app.yinxiang.com/shard/s21/res/25e07069-d8f4-4003-bb9b-b78f09f8b41a.png)
现象:
1) 滚动scrollView时,下载停住了
![](https://app.yinxiang.com/shard/s21/res/b99d5baa-af61-4f67-beb5-c8a1d606d58c.png)
2) 松手下载继续.
程序跑在一个死循环里,每次看有没有事情要做..
有事情就指派给相应地程序去执行.如图:
![](https://app.yinxiang.com/shard/s21/res/b43a7c2a-95d0-4d73-8a56-d7b08d31d927.png)
// Switch to a different app 循环就暂时停掉.
// 死循环里有很多分支.
如果有UI就让它先去处理UI事件(所有其他的事情都暂时停掉,先去处理UI相关的事情)
![](https://app.yinxiang.com/shard/s21/res/bfa75a13-5f4d-4346-bf7e-ad50260fce49.png)
// 方法 scheduleInRunLoop: forMode:
// NSRunLoopCommonModes 一般都用这种模式
// 注意:
1. 选用不是立即启动的连接模式(参数NO)
2. 配置好后,启动下载. (3. “启动下载"的注释打开)
补充: AFNetworking也是用相同的模式:
把需要改的放到一个集合里
![](https://app.yinxiang.com/shard/s21/res/9fc9df48-cfe4-46cb-941e-699427ac224c.png)
![](https://app.yinxiang.com/shard/s21/res/38fd93a8-042e-4394-81b6-381c239d5cf4.png)
// 总结:
![](https://app.yinxiang.com/shard/s21/res/951d6042-f2ae-442c-bf85-d1539b07c991.png)
定时器和ScrollView共存:
// 添加方法稍有不同:
![](https://app.yinxiang.com/shard/s21/res/239a718b-005b-4419-a75b-d61a212f3e31.png)
子线程RunLoop :
// 每个线程都有runLoop,主线程的是系统开启(系统驱动)的.
子线程必须手动启动runLoop , 不会自动运转.
1. 先获取当前线程RunLoop
2.直接run(最懒的方法),不管有事没事都会执行runLoop
// 但是,不好,没事做的时候,最好停下来.
![](https://app.yinxiang.com/shard/s21/res/8f04bd08-dd3a-4888-a619-daad7918612d.png)
// 改进:
1. 指定RunLoop跑在指定的模式下:
// NSDate: 指定一定时间,超时没事做就停下来.
![](https://app.yinxiang.com/shard/s21/res/60e6487d-b91a-477a-a221-badf0ee9a977.png)
代码如下:
![](https://app.yinxiang.com/shard/s21/res/489beaee-1c04-4efc-a35b-1affa09443f6.png)
2. 把RunLoop加到死循环中
3. 通过一个变量来控制当前循环
// 如果下载完毕,停止驱动RunLoop
![](https://app.yinxiang.com/shard/s21/res/b99c88c1-9ff2-4e5e-a1a9-cfbbe983c733.png)
4. 在代理方法中,控制finish
![](https://app.yinxiang.com/shard/s21/res/720aa03d-f7a9-4922-9c8e-5fba33f69efe.png)
5. 完善循环,增加跳出条件:
![](https://app.yinxiang.com/shard/s21/res/4a8dc772-0fa6-48ba-ab6e-609bfb36d86e.png)
// 所以,昨天的,在子线程里,执行下载是不会动的.
释疑:
这里是主线程开了一个子线程,子线程中执行异步下载,相当于子线程又开辟了一个子线程, 最下层的RunLoop需要手动启动.