线程是你的应用程序中可执行的子进程,同时可以与其他子过程并行工作,这种同时执行称为并发。
线程是困难和危险的,能不用尽量不用,但有时这是不可能的。
一.主线程
1.主线程自动有一个运行循环(NSRunLoop)
一个运行循环是一个事件接收者
,通过它可以得知正在发生的事情,如果没有运行循环,线程就不能接收事件。Cocoa事件通常到达主线程的运行循环,这也就是为什么由这些事件调用的代码在主线程上运行的原因了。
2.主线程是界面线程
当用户与界面进行交互时,这些交互被报告为主线程上得事件。当你的代码与界面进行交互时,它也大多在主线程上这样做。
二.实现线程的方法:
- 手动线程
- NSThread
- NSOperation和NSOperationQueue
- GCD(Grand Central Dispatch)
本章只讲前三种方法:
1.手动线程
手动线程的简单方法是将下面的方法发送给某些对象:
[self performSelectorInBackground:@selector() withObject:];
该方法只有一个参数,并且该参数是一个对象类型,如果你想传递多个参数的话,你可以使用NSDictionary将参数打包。
如果你想在子线程中操作主线程中的控件,你可以使用下面的方法:
performSelectorOnMainThread:@selector() withObject: waitUntilDone:];
2.NSThread
NSThread是轻量级的使用线程的方式,但是需要自己管理线程的生命周期,线程同步
NSThread创建和启动线程的主要方式有如下两种:
<1>对象方法
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument ;
创建一个线程对象,如果要启动它要调用下面的方法:
-(void)start;
<2>类方法
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument;
这个方法可以直接生成一个线程并启动它
3.使用NSOperation和NSOperationQueue
使用 NSOperation的方式有两种:
- 直接使用已经定义好的子类,即
NSInvocationOperation
和NSBlockOperation
- 继承自
NSOperation
类,重写main
方法
<1>直接使用已经定义好的子类
NSOperationQueue* queue=[[NSOperationQueue alloc] init];
NSBlockOperation* block=[NSBlockOperation blockOperationWithBlock:^{
//some codes...
}];
[queue addOperation:block];
<2>继承自NSOperation类