swift的多线程

作者: woniu | 来源:发表于2019-11-19 16:48 被阅读0次

    线程的方式有多种多样,主要包含以下三种:Thread、GCD、OperationQueue,下面我们简单的介绍一下他们的使用方式。

    一、OperationQueue

    我们先来看下OperationQueue的所有方法说明,如下:

    @available(iOS 2.0, *)
    open class OperationQueue : NSObject, ProgressReporting {
    
        @available(iOS 13.0, *)
        open var progress: Progress { get }
    
        
        open func addOperation(_ op: Operation)
    
        @available(iOS 4.0, *)
        open func addOperations(_ ops: [Operation], waitUntilFinished wait: Bool)
    
        @available(iOS 4.0, *)
        open func addOperation(_ block: @escaping () -> Void)
    
        
        /// @method addBarrierBlock:
        /// @param barrier      A block to execute
        /// @discussion         The `addBarrierBlock:` method executes the block when the NSOperationQueue has finished all enqueued operations and
        /// prevents any subsequent operations to be executed until the barrier has been completed. This acts similarly to the
        /// `dispatch_barrier_async` function.
        @available(iOS 13.0, *)
        open func addBarrierBlock(_ barrier: @escaping () -> Void)
    
        
        open var maxConcurrentOperationCount: Int
    
        
        open var isSuspended: Bool
    
        
        @available(iOS 4.0, *)
        open var name: String?
    
        
        @available(iOS 8.0, *)
        open var qualityOfService: QualityOfService
    
        
        @available(iOS 8.0, *)
        unowned(unsafe) open var underlyingQueue: DispatchQueue?
    
        
        open func cancelAllOperations()
    
        
        open func waitUntilAllOperationsAreFinished()
    
        
        @available(iOS 4.0, *)
        open class var current: OperationQueue? { get }
    
        @available(iOS 4.0, *)
        open class var main: OperationQueue { get }
    }
    
    

    1、创建线程组,将创建的每个线程放到组中。

            let operationQ = OperationQueue()
    
            let blockOp1 = BlockOperation()
            blockOp1.addExecutionBlock {
                print("11111执行addExecutionBlock")
            }
            operationQ.addOperation(blockOp1)
            
             let blockOp2 = BlockOperation()
             blockOp2.addExecutionBlock {
                 print("22222执行addExecutionBlock")
             }
            operationQ.addOperation(blockOp2)
            
    
            let blockOp3 = BlockOperation()
              blockOp3.addExecutionBlock {
                  print("333333执行addExecutionBlock")
              }
            
            
            operationQ.addOperation(blockOp3)
            ///类似于GCD的dispatch_barrier_async 栅栏
            operationQ.addBarrierBlock {
                print("执行addBarrierBlock")
            }
            
            let blockOp4 = BlockOperation()
            blockOp4.addExecutionBlock {
                 print("4444444执行addExecutionBlock")
             }
            operationQ.addOperation(blockOp4)
    

    addBarrierBlock类似于dispatch_barrier_async起到OC的GCD中的栅栏的作用。输出结果如下:

    22222执行addExecutionBlock
    333333执行addExecutionBlock
    11111执行addExecutionBlock
    执行addBarrierBlock
    4444444执行addExecutionBlock
    

    在栅栏之前线程顺序随机执行,而由于栅栏的存在导致栅栏后面的线程延后执行。

    二、Thread

      func myThread()  {
          print("当前的线程\(Thread.current)\(Thread.main)")
          Thread.sleep(forTimeInterval: 1.0)//线程休眠
          self.perform(#selector(runDelay), with: self, afterDelay: 1.0)
      }
    

    三、GCD

    1、监听多个线程执行完毕

    let group = DispatchGroup()
    let queue = DispatchQueue.global()
    
    group.enter()
    queue.async(group: group) {
         print("任务一")
         group.leave()
    }
    
    group.enter()
    queue.async(group: group) {
          print("任务二")
         group.leave()
    }
    
    group.enter()
    queue.async(group: group) {
         print("任务三")
         group.leave()
    }
    group.notify(queue: DispatchQueue.main) {
         print("完成任务一、二、三")
    }
    

    enter()和leave()必须配合使用,有几次enter就要有几次leave,否则group会一直存在。当所有enter的block都leave后,会执行dispatch_group_notify的block。这一点和OC的GCD一样,本质上来说OC和Swift两者都一样,只不过写的时候语法不同而已。

    2、asyncAfter

    asyncAfter用于延时操作,示例如下:

    DispatchQueue.main.asyncAfter(wallDeadline: DispatchWallTime.now()+3) {
        print("执行延时任务")
    } 
    
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+3) {
        print("执行延时任务")
    }
    

    注意一点, asyncAfter函数并不是在指定时间后执行处理,而是在指定时间后将任务追加到队列中。

    3、DispatchSemaphore

    信号量机制,因为GCD没有Operation的最大并发量机制,所以我们可以通过DispatchSemaphore来为GCD添加上这个功能。

    var arr = [Int]()
    let semaphore = DispatchSemaphore.init(value: 1) // 创建信号量,控制同时访问资源的线程数为1
    for i in 0...100 {
        DispatchQueue.global().async {
                    
            /*
            其他并发操作
            */
                    
            semaphore.wait() // 如果信号量计数>=1,将信号量计数减1;如果信号量计数<1,阻塞线程直到信号量计数>=1
            arr.append(i)
            semaphore.signal() // 信号量计加1
                    
            /*
            其他并发操作
            */
         }
    }
    

    4、concurrentPerform

    concurrentPerform会按照指定次数异步执行任务,并且会等待指定次数的任务异步执行完毕,所以它会阻塞线程,推荐在子线程中使用。

    DispatchQueue.global().async {
         DispatchQueue.concurrentPerform(iterations: 5) { (i) in
             print("执行任务\(i+1)")
         }
         print("任务执行完成")
    }
    
    执行任务4~~~~~~ <NSThread: 0x600003f95080>{number = 6, name = (null)}
    执行任务5~~~~~~ <NSThread: 0x600003f95080>{number = 6, name = (null)}
    执行任务3~~~~~~ <NSThread: 0x600003f9c7c0>{number = 5, name = (null)}
    执行任务1~~~~~~ <NSThread: 0x600003f874c0>{number = 4, name = (null)}
    执行任务2~~~~~~ <NSThread: 0x600003f909c0>{number = 3, name = (null)}
    任务执行完成
    

    相关文章

      网友评论

        本文标题:swift的多线程

        本文链接:https://www.haomeiwen.com/subject/jpbwictx.html