每个应用程序都有一个和用户交互,处理UI事件的线程,称之为主线程,所有的UI操作及交互都必须要放在主线程处理,但是一般应用都会涉及到复杂的处理过程,如网络请求,数据库查询等等,如果我们把这些操作也放在主线程,那么将会造成主线程卡顿,严重影响用户体验~~~
在iOS中,apple提供了三种线程操作方式:NSThread, NSOperation, GCD,我们先看看NSThread的基本使用:
特性
NSThread是这三种中封装层次最高的,层次越高的抽象层度越高,使用起来越方便,也是apple推荐的使用方法。
缺点
需要我们自己管理线程的生命周期,还有同步等问题,同步会有一定的系统开销。
使用方法
线程的两种创建方法:
// 1
let thread = NSThread(target: self, selector: "addDataUseObjc", object: nil)
thread.start()
// 2
NSThread.detachNewThreadSelector("addDataUseObjc", toTarget: self, withObject: nil)
其中第一种方式创建的线程需要我们手动调用start方法执行,第二种是默认自动执行。
除了上面两种创建方法,还有隐式的创建方法:
self.performSelectorInBackground("addDataUseObjc", withObject: nil)
线程间通信
线程 在运行过程中,可能需要与其它线程 进行通信。我们可以使用 NSObject 中的一些方法:
在应用程序主线程 中做事情:
performSelectorOnMainThread:withObject:waitUntilDone:
performSelectorOnMainThread:withObject:waitUntilDone:modes:
在指定 线程 中做事情:
performSelector:onThread:withObject:waitUntilDone:
performSelector:onThread:withObject:waitUntilDone:modes:
在当前线程中做事情:
performSelector:withObject:afterDelay:
performSelector:withObject:afterDelay:inModes:
取消发送给当前线程的某个消息:
cancelPreviousPerformRequestsWithTarget:
cancelPreviousPerformRequestsWithTarget:selector:object:
线程同步
iOS中的 mutex 对应的是 NSLock,它遵循 NSLooking协议,我们可以使用 lock, tryLock, lockBeforeData:来加锁,用 unLock来解锁。
我们可以使用指令 @synchronized 来简化 NSLock的使用,这样我们就不必显示编写创建NSLock,加锁并解锁相关代码。
@synchronized(object)
{
// Everything between the braces is protected by the @synchronized directive.
}
还有其他的一些锁对象,比如:循环锁NSRecursiveLock,条件锁NSConditionLock,分布式锁NSDistributedLock等等,在这里就不一一介绍了,大家去看官方文档吧。