zoukankan      html  css  js  c++  java
  • iOS多线程简介

    前面我们已经讲完了 GCD 的基本概念以及基本使用, 现在让我们来看看第二个多线程开发, NSOperation, 这个类是苹果在 GCD 的基础上再次开发的, 所以并不会太难.


    1.基本概念

    NSOperation和 GCD 不太一样, 它不像 GCD 一样有各种队列, 只保留了自定义队列和全局队列.

    所谓的主队列肯定就是在主线程中运行的, 而自定义队列就是在后台运行的

    PS: 这里需要注意一下, Swift 在 iOS8.1的时候, 就已经把NSInvocationOperation这个方法禁用了, 只剩下NSBlockOperation.


    2.NSOperation队列

        func demo1() {
            // 自定义队列 - 方法一
            var block: NSBlockOperation = NSBlockOperation { () -> Void in
            println("(NSThread.currentThread()) -- NSThread")
            }
            myQueue.addOperation(block)
    
            // 自定义队列 -- 方法二
            // 添加到自定义队列中
            // 所有自定义的队列都在子线程中执行
    
            // 新建线程是有开销的, 所以NSOperationQueue提供了一个方法
            // 在设置同时并发的最大线程时, 如果前一个线程工作完成, 但还没有销毁, 会新建线程
            // 应用场景: 网络开发中, 下载工作! (线程开销: CPU, MEM) 电量
            // 如果是3G, 开3个子线程
            // 如果是 Wifi, 就开6个子线程
    
            // 该方法使用来控制线程数量, 虽然也是不可控的, 但相对来讲可以节省一些资源
            myQueue.maxConcurrentOperationCount = 1
    
            // 并发执行, 线程数量不可控
            for i in 0...9 {
                myQueue.addOperationWithBlock({ () -> Void in
                    println("(NSThread.currentThread()) i -- (i)")
                })
            }
    
            // 在主线程中执行
            NSOperationQueue.mainQueue().addOperationWithBlock { () -> Void in
                println("(NSThread.currentThread()) -- main")
            }
    
        }

    NSOperation 和 GCD 不太一样, 如果我们没有指定最小范围的子线程数量的话, 那么就会申请多个子线程, 但在 NSOperation 中可以设置最大子线程的接近值(maxConcurrentOperationCount).


    3.依赖关系

    在 NSOperation 中不同的还有一种关系叫做依赖关系, 这个和 GCD 的串行队列有些相似, 一旦我们设定好依赖关系之后, 就可以逐步依次往下执行.

        func demo2() {
            var op1 = NSBlockOperation { () -> Void in
                println("(NSThread.currentThread()) -- 下载图片")
            }
            var op2 = NSBlockOperation { () -> Void in
                println("(NSThread.currentThread()) -- 修改图片")
            }
            var op3 = NSBlockOperation { () -> Void in
                println("(NSThread.currentThread()) -- 保存图片")
            }
            var op4 = NSBlockOperation { () -> Void in
                println("(NSThread.currentThread()) -- 更新界面")
            }
    
            // 添加依赖关系, 只有当前一个线程执行完才会去执行下一个依赖的线程
            op2.addDependency(op1)
            op3.addDependency(op2)
            op4.addDependency(op3)
    
            // 添加到线程
            myQueue.addOperation(op1)
            myQueue.addOperation(op2)
            myQueue.addOperation(op3)
    
            // PS: 所有界面的更新都是在主线程中完成的
    //        myQueue.addOperation(op4)
            NSOperationQueue.mainQueue().addOperation(op4)
    
        }

    PS: 注意一点, 这里的依赖关系我们需要写的非常明确, 而且不能循环依赖, 否则程序就会出问题了.


    4.总结

    在一定的程度上, NSOperation的性能比 GCD 的要稍微差一点, 但在大多数情况下是可以忽略不计的, 如果非要使用并发, 那么 NSOperation 是首选的工具.

    但也有一些框架是使用 NSOperation 的接口, 底层却是用 GCD 实现的, 比如 AFNetworking


    好了, 这次我们就讲到这里, 下次我们继续~~

  • 相关阅读:
    [搬运] Tina R329 swupdate OTA 步骤
    摄像头 ISP 调试的经验之谈(以全志 AW hawkview 为例)
    2021 年了 在 WSL2 中使用 adb 、fastboot 的等命令
    wsl2 编译 linux openwrt 项目的时候,经常会出现 bash: -c: line 0: syntax error near unexpected token `('
    sipeed v833 硬件验证以及开发记录(2021年5月18日)
    Allwinner & Arm 中国 & Sipeed 开源硬件 R329 SDK 上手编译与烧录!
    把 R329 改到 ext4 sdcard 启动变成 Read-Only 系统,导致没有文件修改权限后如何修复。
    linux kernel version magic 不一致导致的模块 加载 (insmod) 不上
    剑指 Offer 17. 打印从1到最大的n位数
    剑指 Offer 16. 数值的整数次方
  • 原文地址:https://www.cnblogs.com/iOSCain/p/4529332.html
Copyright © 2011-2022 走看看