线程的方式有多种多样,主要包含以下三种: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)}
任务执行完成
网友评论