Mac中多线程的使用
mac中gcd的使用
import Cocoa
class ViewController: NSViewController {
// public static let userInitiated: DispatchQoS
// public static let 'default': DispatchQoS
// public static let utility: DispatchQoS
// public static let background: DispatchQoS
//根据优先级获取队列
let queue4 = DispatchQueue.global(qos: .userInitiated)
//创建串行分发队列
let queue1 = DispatchQueue(label: "macdev.io.exam") //创建私有
let main = DispatchQueue.main //获取主线程分发队列
//创建并行分发队列
let queue = DispatchQueue(label: "macdev.io.exam", qos: .background, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
override func viewDidLoad() {
super.viewDidLoad()
//延时执行
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
print("do some work after 3s!")
}
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
//添加异步任务到队列
func asyncTask() {
let queue = DispatchQueue(label: "macdev.io.exam")
queue.async {
print("1do some tasks")
}
print("2")
//2 1
}
//添加同步队列
func syncTask() {
let queue = DispatchQueue(label: "name")
queue.sync {
print("1")
}
queue.sync {
print("2")
}
print("3")
// 1 2 3
}
//线程切换 执行完成后将计算结果或状态通知到主线程或其他队列进异步处理
func singleTask() {
let textFiled = NSTextField.init()
let queue = DispatchQueue(label: "name")
queue.async {
var sum = 0
for i in 1...10 {
sum += i
}
DispatchQueue.main.async {
//更新计算过
textFiled.integerValue = sum
}
}
}
//多线程组
func groupTask() {
let group = DispatchGroup() //创建组
let queue = DispatchQueue(label: "name")
queue.async {
print("do work 1 here")
}
queue.async {
print("do work 2 here")
}
//创建一个任务
let workItem = DispatchWorkItem(qos: .userInitiated, flags: .assignCurrentContext) {
print("3group comlete")
}
group.notify(queue: queue, work: workItem)
// 1 2 3
}
//动态控制组任务 多个网络请求完成后进行统一UI更新
//发起前调用 dispatch_group_enter(group) 接收后调用dispatch_group_leave(group)
let kServerBaseUrl = "http:www.iosxhelper.com/SAPI"
func groupEnterLeaveTask() {
let group = DispatchGroup()
let httpClient = HTTPClient()
let urlString = "\(kServerBaseUrl)\("/VersionCheck")"
let url = URL(string: urlString)
group.enter()
httpClient.get(url!, parameters: nil, success: { (responseObject: Any?) ->Void in
print("1 first get data = \(responseObject)")
group.leave()
}) { (error: Error?) -> Void in
}
group.enter()
httpClient.get(url!, parameters: nil, success: { (responseObject: Any?) ->Void in
print("2 first get data = \(responseObject)")
group.leave()
}) { (error: Error?) -> Void in
}
let workItem = DispatchWorkItem(qos: .userInitiated, flags: .assignCurrentContext) {
print("3group complete")
}
group.notify(queue: DispatchQueue.main, work: workItem)
// 1 2 3
}
//优化循环性能 dispatch_apply
func gcdapply() {
for i in 0..<10 {
print("ad\(i)")
}
//优化
DispatchQueue.concurrentPerform(iterations: 2) { (i) in
print("i")
}
}
let queue_sus_resum = DispatchQueue(label: "quene.name")
//任务暂停和唤醒
func suspendQueue() {
queue_sus_resum.suspend()
}
func resumeQueue() {
queue_sus_resum.resume()
}
//使用信号量控制首先资源
//初始化信号量
var semahore = DispatchSemaphore(value: 10)
@IBAction func waitAction(_ sender: AnyObject){
self.queue.async {
self.semahore.wait()
print("begin work!")
}
}
@IBAction func signalAciton(_ sender: AnyObject){
semahore.signal()
}
//使用barrier控制并发任务
func barrierControlTask() {
let queue = DispatchQueue(label: "myBackgroundQueue", qos: .userInitiated, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
queue.async {
print("Do some work 1 here")
}
queue.async {
print("Do some work 2 here")
}
queue.async {
print("Do some work 3 here")
}
queue.async(flags: .barrier) {
print("do some barrire 4")
}
queue.async {
print("Do some work 5 here")
}
//(231不定) 、定顺序4 5
}
}
//MARK:- HTTPClient工具类的实现
typealias HTTPSesionDataTaskCompetionBlock = (_ response: URLResponse?, _ responseObject: Any?, _ error: Error) -> ()
class HTTPClientSessionDelegate: NSObject, URLSessionDataDelegate {
var taskCompletionHandler: HTTPSesionDataTaskCompetionBlock?
var buffer: Data = Data()
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
//缓存接收到的数据
self.buffer.append(data)
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
let responseStr = String(data: self.buffer, encoding: String.Encoding.utf8)
print("didReceive data =\(String(describing: responseStr))")
if let callback = taskCompletionHandler {
callback(task.response,responseStr,error!)
}
//释放session资源
session.finishTasksAndInvalidate()
}
}
//HTTPClient类 定义外部访问接口GET/POST,穿件URLSessionDataTask任务实例,实现代理功能路由到具体的协议代理处理类
class HTTPClient: NSObject {
var sessionConfiguration = URLSessionConfiguration.default
lazy var operationQueue: OperationQueue = {
let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 1
return operationQueue
}()
lazy var session: URLSession = {
return URLSession(configuration: self.sessionConfiguration, delegate: self, delegateQueue: self.operationQueue)
}()
//代理缓存
var taskDelegates = [AnyHashable: HTTPClientSessionDelegate?]()
//资源保护锁
var lock = NSLock()
func get(_ url: URL, parameters: Any?, success:@escaping (_ responseData: Any) -> Void,failure:@escaping (_ error: Error?) -> Void) {
var request: URLRequest
let postStr = self.formatParas(paras: parameters!)
if let paras = postStr {
let baseURLString = url.path + "?" + paras
request = URLRequest(url: URL(string: baseURLString)!)
}
else
{
request = URLRequest(url: url)
}
let task = self.dataTask(with: request, success: success, failure: failure)
task.resume()
}
func post(_ url: URL, parameters: Any?, success: @escaping(_ responseData: Any?) -> Void, failure: @escaping(_ error: Error?) -> Void) {
var request = URLRequest(url: url)
request.httpMethod = "POST"
let postStr = self.formatParas(paras: parameters!)
if let str = postStr {
let postData = str.data(using: String.Encoding.utf8)!
request.httpBody = postData
}
let task = self.dataTask(with: request, success: success, failure: failure)
task.resume()
}
//参数格式化
func formatParas(paras parameters: Any) -> String? {
var postStr: String?
if (parameters is String) {
postStr = parameters as? String
}
if (parameters is [AnyHashable: Any]) {
let keyValues = parameters as! [AnyHashable: Any]
var tempStr = String()
var index = 0
for(key, obj) in keyValues {
if index > 0 {
tempStr += "&"
}
let kv = "\(key)=\(obj)"
tempStr += kv
index += 1
}
postStr = tempStr
}
return postStr
}
func add(_ completionHandler: @escaping HTTPSesionDataTaskCompetionBlock, for task: URLSessionDataTask) {
let sessionDelegate = HTTPClientSessionDelegate()
sessionDelegate.taskCompletionHandler = completionHandler
self.lock.lock()
self.taskDelegates[(task.taskIdentifier)] = sessionDelegate
self.lock.unlock()
}
func dataTask(with request: URLRequest, success: @escaping(_ responseData: Any?) -> Void,failure: @escaping(_ error: Error?) -> Void) -> URLSessionDataTask {
let dataTask = self.session.dataTask(with: request)
let complectionHandler = {
(response: URLResponse?, responseObject: Any?, error: Error?) -> (Void) in
if error != nil {
failure(error)
}
else
{
success(responseObject)
}
}
self.add(complectionHandler, for:dataTask)
return dataTask
}
}
//代理协议
extension HTTPClient: URLSessionDataDelegate {
//数据接收
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
let sessionDelegate = self.taskDelegates[(dataTask.taskIdentifier)]
if let delegate = sessionDelegate {
delegate?.urlSession(session, dataTask: dataTask, didReceive: data)
}
}
//请求完成的
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
let sessionDelegate = self.taskDelegates[(task.taskIdentifier)]
if let delegate = sessionDelegate {
delegate?.urlSession(session, task: task, didCompleteWithError: error)
}
}
}
//MARK:- gcd的使用
class MyObject: NSObject {
private var internalState: Int
private let queue:DispatchQueue
override init() {
queue = DispatchQueue(label: "queue.name")
internalState = 0
super.init()
}
var state: Int {
get {
return queue.sync { internalState }
}
set (newState) {
queue.sync {
internalState = newState
}
}
}
}
//防止线程死锁
class MyCalss {
var interface: String?
var key = DispatchSpecificKey<Void>()
lazy var queue: DispatchQueue = {
let queue = DispatchQueue(label: "queue.name")
queue.setSpecific(key: self.key, value: ())
return queue
}()
func readInterface() -> String? {
var result: String?
if DispatchQueue.getSpecific(key: self.key) != nil {
//已经是当前队列,则直接返回值
return self.interface
}
self.queue.sync {
result = self.interface
}
return result
}
func updateInterface(_ newInterface: String?) {
let value = newInterface
self.queue.sync {
self.interface = value
}
}
}
operation的使用
import CoreFoundation
//OperationQueue的属性
//open class OperaitonQueue: OperationQueue{
//增加操作任务到队列
// func addOperation(_ op: Operaiton);
//增加多个操作任务到队列
// func addOperations(_ ops: [Operation], waitUntilFinished wait: Bool)
//增加基于闭包块定义的操作任务队列
// func addOperation(_ block: @escaping () -> Void)
//队列所有的操作任务
// var operations: [Operation] {get}
//所有操作任务操作个数
// var operstionCount: Int {get}
//最大允许的并发数,设置为1时等价于GCD的串行分发队列,大于1时相当于并发队列
// var maxConcurrentOperationCount: Int
//队列挂起状态
// var isSuspended: Bool
//队列名称
// var name: String?
//队列服务质量
// var qualityOfService: QualityOfService
//队列对应的底层GCD的队列,从这里可以印证NSOperaitonQueue在GCD基础上做了封装
// unowned(unsafe) open var underlyingQueue: DispatchQueue? /actually retain/
//取消所有任务
//func cancelAllOperations()
//等待所有任务完成
// func waitUntilAllOperationsAreFinished()
//获取当前正在执行的任务队列
// var current: OperationQueue? {get}
//获取当前的主线程分发队列
// var main: OperationQueue {get}
//}
class OperationQueueViewController: NSViewController {
convenience init() {
self.init()
}
override func viewDidLoad() {
super.viewDidLoad()
}
func OperationBlockTask() {
let opt = BlockOperation()
opt.addExecutionBlock {
print("Run in block 1")
}
opt.addExecutionBlock {
print("Run in block 2")
}
opt.addExecutionBlock {
print("Run in block 3")
}
opt.addExecutionBlock {
print("Run in block 4")
}
OperationQueue.current!.addOperation(opt)
//执行结果无顺序
}
let leftImageView: NSImageView! = nil
//使用HTTPImageOpersiotn类下载网络图片
func downLoadTask() {
let url1 = URL(string: "http://www.imag1.png")
//新建操作任务
let op1 = HTTPImageOpersiton(imageURL: url1)
op1.downCompetionBlock = {(_ image: NSImage?) -> () in
if let img = image {
self.leftImageView.image = img
}
}
OperationQueue.main.addOperation(op1)
}
//设置任务间的依赖
func dependencyTask() {
let aQueue = OperationQueue()
let opt1 = BlockOperation()
opt1.addExecutionBlock {
print("run in block 1")
}
let opt2 = BlockOperation()
opt2.addExecutionBlock {
print("run in block 2")
}
opt2.addDependency(opt1)
aQueue.addOperation(opt1)
aQueue.addOperation(opt2)
//1 2
//设置Operation执行完的回调
opt1.completionBlock = {
print("run all Block opreation")
}
//取消单个操作
opt2.cancel()
//取消queue中所有的操作
OperationQueue.current?.cancelAllOperations()
//暂停或回复队列的执行
//暂停执行
OperationQueue.current?.isSuspended = true
//回复执行
OperationQueue.current?.isSuspended = false
}
//执行任务的优先级
func prepertyTask() {
let aQueue = OperationQueue()
let opt1 = BlockOperation()
opt1.queuePriority = .veryLow
opt1.addExecutionBlock {
print("run in block 1")
}
let opt2 = BlockOperation()
opt2.queuePriority = .veryLow
opt2.addExecutionBlock {
print("run in block 2")
}
let opt3 = BlockOperation()
opt3.queuePriority = .veryHigh
opt3.addExecutionBlock {
print("run in block 3")
}
aQueue.addOperations([opt1,opt2,opt3], waitUntilFinished: false)
}
}
/***
*Operaiton是一个抽象类 其子线程的几个关键方法
*是否允许并发执行
*var isAsynchronous: Bool {get}
*kvo属性方法,表示任务执行状态
*var isExecuting: Bool {get}
*kvo属性方法,表示任务是否执行完成
*var isFinished: Bool {get}
*任务启动前的方法,满足执行条件时,启动线程执行main方法
*func start()
*实现具体的任务逻辑
*func mian()
**/
typealias DownCompletionBlock = (_ image: NSImage?) -> ()
class HTTPImageOpersiton: Operation {
var url: URL!
var downCompetionBlock : DownCompletionBlock?
var _executing = false
var _finished = false
deinit {
}
override init() {
super.init()
}
convenience init(imageURL url: URL?) {
self.init()
self.url = url!
}
//表示是否允许并发
override var isAsynchronous: Bool {
return true;
}
override var isExecuting: Bool{
return _executing
}
override var isFinished: Bool{
return _finished
}
override func start() {
if self.isCancelled {
self.willChangeValue(forKey: "isFinished")
_finished = true
self.didChangeValue(forKey: "isFinished")
return
}
self.willChangeValue(forKey: "isExecuting")
Thread.detachNewThreadSelector(#selector(self.main), toTarget: self, with: nil)
_executing = true
self.didChangeValue(forKey: "sExecuting")
}
func complete() {
self.willChangeValue(forKey: "isFinished")
self.willChangeValue(forKey: "isExecuting")
_executing = false
_finished = true
self.didChangeValue(forKey: "isExecuting")
self.didChangeValue(forKey: "isFinished")
}
override func main() {
let image = NSImage(contentsOf: self.url)
if let callback = self.downCompetionBlock {
callback(image)
}
self.complete()
}
}
Thread的使用
/***
*获取当前运行的线程
*class var current: Thread {get}
*是否支持多线程
*class func isMultiTreaded() -> Bool
*是否是主线程的属性
*var isMainThread: Bool {get}
*获取主线程
*calss var main: Thread {get}
*线程的配置参数属性和方法如下
*线程的local数据字典
*var threadDictionary: NSMutableDictionary {get}
*线程优先级
*class func threadPriority() -> Double
*修改优先级
*class func setThreadPriority(_ p: Double) ->Bool
*线程服务质量
*var qualityOfService: QualityOfService
*线程名称
*var name: String?
*栈大小
*var stackSize: Int
**********************
*线程执行的各种状态属性参数
*是否正在执行
*var isExecuting: Bool {get}
*是否完成
*var isFinished: Bool {get}
*是否取消
*var isCancelled: Bool {get}
********线程的控制方法
*取消执行
*func cancel()
*启动执行
*func start
*线程执行的主方法,子类化线程实现这个方法即可
*func main()
*休眠到制定日期
*class func sleep(until date: Date)
*定期休眠
*class fund sleep(forTimeInterval ti:TimeInterval)
*退出线程
*class func exit()
*/
class ThirdViewController: NSViewController {
/***
*Thread是底层pthread线程的封装,提供更多的灵活性
*可以设置线程的服务质量
*可以设置线程栈大小
*线程提供local数据字典,可以存储键/值数据
*其优势 实时性高 与RunLoop结合,提供更为灵活高效的线程管理方式
*缺点 创建线程代价较大,需要同时占有应用和内核内存
**/
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
}
// 1startTread创建线程
func startThread() {
Thread.detachNewThreadSelector(#selector(self.compulterSum), toTarget: self, with: nil)
}
@objc func compulterSum() {
var sum = 0
for i in 0..<10 {
sum += i
}
print("sum")
}
//2.直接使用Thread创建
func createThread() {
let thread = Thread(target: self, selector: #selector(self.compulterSum), object: nil)
thread.name = "ThreadName1"
thread.start()
}
////////////4.线程中共享资源保护
func shareTask() {
let count = UnsafeMutablePointer<Int32>.allocate(capacity: 1)
count.pointee = 2
OSAtomicIncrement32(count)
print("var =\(count)")
OSAtomicDecrement32(count)
print("var = \(count)")
}
/////枷锁
func lockTask() {
let lock = NSLock()
if lock.try() {
//do some work
//释放资源
lock.unlock()
}
}
/////递归锁NSRecursiveLock主要用在循环和递归中,保证同一线程多次枷锁操作不产生死锁
//在同一个类中多个方法,递归操作,循环处理中对受保护资源的访问
func recursiveTask() {
let theLock = NSRecursiveLock()
for i in 0..<10 {
theLock.lock()
//do some work
theLock.unlock()
}
}
}
//3. 子类化Thread 封装成Thread的子类进行独立处理,完成的结果可以通知或代理通知到主线程
//通过重载main方法实现子类化,加上autoreleasepool自动释放池,确保线程中国及时释放
protocol ImageDownloaddelegate :class {
func didFinishDown(_ image: NSImage?)
}
class WrokThread: Thread {
var url: URL!
weak var delegate: ImageDownloaddelegate?
convenience init(imageURL url: URL?) {
self.init()
self.url = url!
}
override func main() {
print("start main")
autoreleasepool {
let image = NSImage(contentsOf: url)
if let downloadDelegate = delegate {
downloadDelegate.didFinishDown(image)
print("end mian")
}
}
}
}
//5//NSConditionLock条件锁
//condition为一个整数参数,满足条件时获得锁,解锁时可以设置condition条件
//lock、lockWhenCondition与unlock、unlockWhenCondition可以任意组合
class NSConditionLockTest: NSObject {
lazy var condition : NSConditionLock = {
let c = NSConditionLock()
return c
}()
var queue = [String]()
@objc func doWork1() {
print("work1 begin")
while true {
sleep(1)
self.condition.lock()
print("do lock work 1")
self.queue.append("a1")
self.queue.append("a2")
self.condition.unlock(withCondition: 2)
}
print("doWork1 end")
}
@objc func doWork2() {
print("work2 begin")
while true {
sleep(1)
self.condition.lock(whenCondition: 2)
print("do lock work 2")
self.queue.removeAll()
self.condition.unlock()
}
print("doWork1 end")
}
func doWrok() {
self.performSelector(inBackground: #selector(self.doWork1), with: nil)
self.perform(#selector(self.doWork2), with: nil, afterDelay: 1)
}
}
/*****
*6 NSCondition 通过一些条件控制多个线程协作完成任务,当条件不满足时线程等待,条件满足时通过
*发送signal信号来通知等待的线程继续处理
**/
class NSConditionTest: NSObject {
var completed = false
lazy var condition: NSCondition = {
let c = NSCondition()
return c
}()
func clearCondition() {
self.completed = false
}
@objc func doWork1() {
print("doWork1 Begin")
self.condition.lock()
while !self.completed {
self.condition.wait()
}
print("doWork1 End")
self.condition.unlock()
}
@objc func doWork2() {
print("doWork2 Begin")
//do somework
self.condition.lock()
self.completed = true
self.condition.signal()
self.condition.unlock()
print("doWork2 End")
self.condition.unlock()
}
func doWork() {
self.performSelector(inBackground: #selector(self.doWork1), with: nil)
self.perform(#selector(self.doWork2), with: nil, afterDelay: 1)
}
/***
*doWork1 begin
*doWork2 begin
*doWork2 end
*doWork1 end
**/
}
RunLoop中Timer的使用
/****
*RunLoopModel中属性
*connectionReplay-Mode系统内部监控NSConection
*defalutRunLoopModel
*commonModes
*modelPaneRunLoopMode
*eventTrackingRunLoopMode 键盘外设 触控
***/
class RunLoopController: NSViewController {
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
convenience init() {
self.init()
}
var timer: Timer?
var timeCount: Int32 = 100
override func viewDidLoad() {
super.viewDidLoad()
// //获取runloop
// let runLoop = RunLoop.current
// let runLoop2 = CFRunLoopGetCurrent
// CFRunLoopStop(runLoop as! CFRunLoop)
// CFRunLoopStop(CFRunLoopGetCurrent())
// //
// runLoop.run()
// runLoop.run(until: Date())
// runLoop.run(mode: RunLoop.Mode, before: Date) -> Bool
//设置time的mode为Common 防止其他高优先级Mode事件影响定时器的运行
timer = Timer(timeInterval: 1, target: self, selector:#selector(self.doFireTimer), userInfo: nil, repeats: true)
}
@objc func doFireTimer() {
if timeCount <= 0 {
return
}
timeCount -= 1
//赋值UI
}
//GCDTimer不受界面滑动的影响
var gcdTimer: DispatchSourceTimer?
func gcdTimerTest() {
gcdTimer = DispatchSource.makeTimerSource(flags: DispatchSource.TimerFlags.init(rawValue: 1), queue: DispatchQueue.main)
gcdTimer?.setEventHandler(handler: {
//定时器
print("timer out")
})
//配置为重复执行的定时器
gcdTimer?.scheduleRepeating(deadline: .now() + 1, interval: 1)
//单次定时
gcdTimer?.scheduleOneshot(deadline: .now() + 1)
//启动定时器
gcdTimer?.resume()
}
func addRunLoopObserver() {
var _self = self
//定义观察者的context
var observerContext = CFRunLoopObserverContext(version: 0, info: &_self, retain: nil, release: nil, copyDescription: nil)
//创建观察者
let observer = CFRunLoopObserverCreate(kCFAllocatorDefault, CFRunLoopActivity.allActivities.rawValue, true, 0, self.observerCallBackFunc(), &observerContext)
if observer != nil {
//增加当前RunLoop观察者
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, CFRunLoopMode.defaultMode)
}
}
//观察者的状态回调s函数
func observerCallBackFunc() -> CFRunLoopObserverCallBack {
return {(observer, activity, context) -> Void in
switch activity {
case CFRunLoopActivity.entry: //开始进入
print("RunLoop entry")
break
case CFRunLoopActivity.beforeTimers: //定时器即将到时
print("RunLoop beforeTimers")
break
case CFRunLoopActivity.beforeSources: //原事件即将触发
print("RunLoop beforeSources")
break
case CFRunLoopActivity.beforeWaiting: //即将进入休眠
print("RunLoop beforeWaiting")
break
case CFRunLoopActivity.afterWaiting: //即将唤醒
print("RunLoop afterWaiting")
break
case CFRunLoopActivity.exit: //退出
print("RunLoop exit")
break
case CFRunLoopActivity.allActivities: //所有活动状态
print("RunLoop allActivities")
break
default:
break
}
}
}
}

浙公网安备 33010602011771号