在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
多线程 是一个应用程序内多个代码的执行路径,执行线程,同时在同一时间里执行不同的任务。 三种: 1、NSTread 2、Cocoa NSOperation (NSOperation,NSOperationQueue) 3、GrandCentralDispatch:GCD 1\NSTread 相对最简单,需要自己管理线程的生命周期和线程同步(加锁会有一定的系统开销) 两种应用方式: 需要传递三个参数: selector:线程执行方法"" target:方法所在的对象 argument:传递给方法的参数,可选nil
一、直接创建线程,自动运行线程 // Class Method class func detachNewThreadSelector(selector:Selector,toTarget target:AnyObject,withObject argument:AnyObject?) 二、先创建一个线程对象,手动运行线程,在运行之前可设置线程优先级等信息。 convenience init(target:AnyObject,selector:Selector,object argument:AnyObject?)
for example // download image method func downloadImage() { var imageUrl = "https://www.baidu.com/img/bdlogo.png" var data = NSData.dataWithContentsOfURL(NSURL.URLWithString(imageUrl),options:nil,error:nil) println(data.length) }
override func viewDidLoad(){ super.viewDidLoad() // 第一种方式 NSThread.detachNewThreadSelector("downloadImage",toTarget:self,withObject:nil)
// 第二种方式 var downloadImageThread = NSThread(target:self,selector:"downloadImage",object:nil) dowloadImageThread.start() } 线程同步,通过锁来实现,每个线程有一个锁,锁 与 特定的线程关联。 for example // 定义两个线程 var thread1,thread2:NSThread? // 线程条件 let condition1 = NSCodition() let condition2 = NSCodition() // two method for thread func method1(sender: AnyObject) { for var i = 0; i <10; i++ { println("thread 1 running \(i)") sleep(1) if i == 2 { thread2!.start() // lock condition1.lock() condition1.wait() condition1.unlock() } } println(thread 1 over) // condition2.signal() } // func method2(sender:AnyObject) { for var i=0;i<10;i++ { println("thread 2 running \(i)") sleep(1) if i ==2 { // active thread 1 condition1.signal() // lock condition2.lock() condition2.wait()// stop waitting condition2.unlock() } } println("thread 2 over") } // RUN thread2 = NSThread (target:self , selector:"method2:",object:nil) thread1 = NSThread(target:self,selector:"method1",object:nil) 控制台输出 thread 1 running 0 thread 1 running 1 thread 1 running 2 thread 2 running 0 thread 2 running 1 thread 2 running 2 thread 1 running 3 thread 1 running 4 thread 1 running 5 thread 1 running 6 thread 1 running 7 thread 1 running 8 thread 1 running 9 thread 1 over thread 2 running 3 thread 2 running 4 thread 2 running 5 thread 2 running 6 thread 2 running 7 thread 2 running 8 thread 2 running 9
线程1 2是同步关系,启动2,挂起 1,激活1,挂起2,有效避免了线程1占用一个资源时,引起线程2不能访问的问题。
NSOperation 两种方式 一 两个子类 NSInvocationOperation NSBlockOperation // creat instance var operation = NSInvocationOperation(target:self,selector:"dowloadImage",object:nil) var queue = NSOperationQueue() queue.addOperation(operation) 后台建立一个线程 Queue队列中可以加入很多个operation 可以把它看做是一个线程池子,可以设置线程池中的线程数,即并发操作数。 默认是:-1,-1表示没有限制,同时运行队列中的全部操作。 queue.maxConcurrentOperationCount = 6 // ervery operation come to an end var completionBlock:(()->Void)? operation.completionBlock = completionBlock dispatch_after(dispatch_time(DISPATCH_TIME_NOW,4),dispatch_get_main_queue(),{println("complete")})
// cancell queue.cancelAllOperations()
二 继承NSOperation 把子类的对象放到NSOperationQueue队列中 ,一旦加入,就处理这个,直到操作完成,队列被释放。 // creat DrinkOperation.swift 继承 NSOperation 且 实现main方法 import UIKit class DrinkOperation:NSOperation{ override func main() { println("drink") } }
// e.g. // creat a instance var queue1 = NSOperationQueue() // creat a operation var drinkOperation = DrinkOperation() // add queue1.addOperation(drinkOperation)
Grand Central Dispatch 多核编程 底层也是用线程实现,queue可以接受任务,先到先执行顺序来执行,也可以并发或串行执行。 同步或异步 优点多多:基于C,融入面向对象,Block,易用,性能上自动根据系统负载来增减线程数量,无需加锁。 三种方法: 一 自己创建队列 func dispatch_queue_create(label:UnsafePointer<Int8>,attr:dispation_queue_attr_t!)->dispatch_queue_t! label:参数代表队列名称,可以任意名 DISPATCH_QUEUE_CONCURRENT 并行 DISPATCH_QUEUE_SERIAL 串行 //e.g. var serialQueue = dispatch_queue_create("serialQueue_1",DISPATCH_QUEUE_SERIAL) var concurrentQueue = dispatch_queue_create("concurrentQueue_1",DISPATCH_QUEUE_CONCURRENT) 二 获取系统的全局队列 func dispatch_get_global_queue(identifier:Int,flags:UInt)->dispatch_gueue_t! 参数 identifier 执行优先级 ,4个优先级 DISPATCH_QUEUE_PRIORITY_HIGH DISPATCH_QUEUE_PRIORITY_DEFAULT DISPATCH_QUEUE_PRIORITY_LOW DISPATCH_QUEUE_PRIORITY_BACKGROUND 非常低的有相机,用于不太关心的后台任务 // e.g. var globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0) 三 在主线程的Main dispatch queue 在主线程里执行的队列(只有一个主线程) 一切跟UI相关的操作都放到主线程中执行 func dispatch_get_main_queue()->dispatch_queue_t! // e.g. var mainQueue = dispatch_get_main_queue()
追加任务到队里的 两个方法: async = asynchronous 异步 func dispatch_async(queue:dispatch_queue_t!,block:dispatch_block_t!) 第一个参数:GCD队列 // e.g. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),{()->Void in // 耗时代码块 //执行完 调用主线程刷新界面 dispatch_async(dispatch_get_main_queue(),{()->Void in //通知主线程刷新
}) })
二 dispatch_sync 同步追加Block 与之前相反,block结束之前,dispatch_sync会一直等待,等待队列前面的所有任务完成后才执行追加的任务。 func dispatch_sync() // e.g. dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),{()->Void in println("sync1") }) 加到 global_queue异步队列中,不会造成锁死,但会一直等待代码执行完毕。 如果加到main_queue中,在主线程中添加任务操作,就会引起死锁。 // e.g. dispatch_sync(dispatch_get_main_queue(),{()->Void in print("sync2") })
暂停和继续执行队列 func dispatch_suspend() 暂停 func dispatch_resume() 继续 suspend 使 suspension reference count +1 resume -1 count>0 queue就保持挂起状态 如果挂起了 一个 queue 或者 source 那么销毁他之前,先对其进行恢复。 var concurrentQueue = dispatch_queue_create("concurrentQueue_1",DISPATCH_QUEUE_CONCURRENT) // stop dispatch_suspend(concurrentQueue) // go on dispatch_resume(concurrentQueue) 只执行一次 用于单例 dispatch_once 延时:指定时间后把任务追加到 dispatch queue里面 dispatch_after func dispatch_time(when:XX,delta:Int64)->dispatch_time_t delta单位非常小,到秒要乘以 NSEC_PER_SEC let deltaT = 2.0 *Double(NSEC_PER_SEC) let dTime =dispatch_time(DISPATCH_TIME_NOW,Int64(deltaT)) dispatch_after(dTime,dispatch_get_global-global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0) {()->Viod in println("延时2秒执行") })
多个任务都结束的一个全部结束:dispatch_barrier_async 当执行任务更新数据时,会出现数据不一样的情况。 for i in 1...100 { dispatch_async(queue,{()->Void in println("\(i)")
}) } 虽然使用dispatch_barrier_async可以避免 但是有另一方法, semaphore 信号量 var semaphore = dispatch_semaphore_creat(1)//初始值为1 for i in 1...100 { dispatch_async(queue,{()->Void in
dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER) println("\(i)") dispatch_semaphore_signal(semaphore) }) }
|
请发表评论