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多线程

    swift 2.0 和 3.0的多线程的区别 swift 2.0多线程的基础使用 dispatch_async(d...

  • iOS-Swift相关

    swift程序. 1.Swift多线程之Operation:异步加载CollectionView图片2.Swift...

  • Swift多线程:GCD进阶,单例、信号量、任务组

    Swift多线程:GCD进阶,单例、信号量、任务组 Swift多线程:GCD进阶,单例、信号量、任务组

  • 多线程

    参考文章:iOS多线程--彻底学会多线程之『GCD』Swift 3.0 GCD和DispatchQueue 使用解...

  • swift3多线程之GCD

    多线程可以说ios进阶高级程序员的必修课,swift2的时候GCD还是继承的OC中多线程的C API,在swift...

  • iOS/Swift多线程之---如何避免数据竞争(Data ra

    iOS/Swift多线程之---如何避免数据竞争(Data race)

  • Swift 5.x 多线程

    Swift多线程编程方案: Thread Cocoa Operation (Operation 和 Operati...

  • GCD

    iOS多线程 Swift4 GCD深入解析swift GCD 的一些高级用法GCD 之线程组(Dispatch G...

  • 多线程

    iOS常见的多线程方案 GCD源码:https://github.com/apple/swift-corelibs...

  • Swift:与OC混编

    目录一,条件编译二,KVO/KVC三,Swift调用OC四,OC调用Swift五,字符串六,多线程 一,条件编译 ...

网友评论

    本文标题:swift的多线程

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