先来理解一下线程和进程的区别和联系

区别:线程是CPU独立运行和独立调度的基本单位,可以理解为一个进程中执行的代码片段。

联系:进程是线程的容器,真正完成代码执行的是线程,而进程则作为线程的执行环境,一个程序中至少包含一个进程,一个进程至少包含一个线程,一个进程中的多个线程共享当前进程所拥有的全部资源。

多线程开发的优缺点:

优点:使用多线程开发可以把程序中占据时间长的任务放到后台去处理,如图片、视频的下载,还可以发挥多核处理器的优势,并发执行让系统运行的更好更流畅,用户体验更好

缺点:大量的线程降低代码的可读性,需要更多的内存空间,而且当多个线程对一个资源出现争夺的时候要注意线程安全的问题

线程的使用也不是无节制的,iOS中得主线程的堆栈大小是1M,从第二个线程开始都是512K,这些数值不能通过编译器开关或者API函数更改。

多线程开发时要注意更新UI界面时,处理界面和用户之间的交互事件一定要在主线程中处理


iOS创建多线程主要有三种方法:NSThread、NSOperatio和GCD(Grand Central Dispatch)

一、NSThread

轻量级,使用简单,每个NSThread对象对应一个线程,需要自己管理线程的生命周期、线程同步、加锁、睡眠以及唤醒等。线程同步对数据的加锁会有一定的系统开销 .

开启一个线程的3中方式:

//第一种,使用NSThread开启线程,手动开启
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(selector1) object:nil];
    //开始执行
start];
 
 
    //第二种,NSThread自动开启
[NSThread detachNewThreadSelector:@selector(selector3) toTarget:self withObject:nil];
 

    //第三种, 用的较多,在子线程中完成
    //NSObject的方法, 开启一个线程执行耗时的操作
//开启后台线程执行任务的方法,方法本身是在主线程中执行的,而选择器指定的方法是在后台线程中进行的
    [self performSelectorInBackground:@selector(selector2) withObject:nil];
//开启后台线程执行任务的方法,方法本身是在主线程中执行的,而选择器指定的方法是在后台线程中进行的
 
 
void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg
 {
     
 }
 
 

//在后台中通知主线程执行任务的方法
void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
 {
    //得到当前的进程
    //[NSThread currentThread];
    //线程休眠
    //[NSThread sleepForTimeInterval:1.0];
 }



二、NSOperation

面向对象,不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。NSOperation的是对线程的高度抽象,在项目中使用它, 会使项目的程序结构更好,子类化NSOperation的设计思路,是具有面向对象的优点,使得实现是多线程支持,而接口简单,可以在复杂项目中使用。

NSInvocationOperation * operation = [[NSInvocationOperationalloc] initWithTarget:self selector:@selector(printLargeNumber) object:nil];
     
    NSInvocationOperation * operation2 = [[NSInvocationOperationalloc] initWithTarget:self selector:@selector(test) object:nil];
    //创建一个操作队列, 队列FIFO, 先进先出
    NSOperationQueue * queque = [[NSOperationQueue alloc] init];
    //设置最大并发个数
    [queque setMaxConcurrentOperationCount:2];
addOperation:operation];
addOperation:operation2];



三、GCD(共产党)

GCD是基于C语言的面向对象的苹果开发的一个多线程编程的解决方案。iOS4.0+才能使用,比NSThread, NSOperation更为高效和强大,是苹果推荐使用的多线程技术。GCD本身非常简单易用,对于不复杂的多线程操作,会节省代码量,而Block参数的使用,会使代码更为易读,可以在简单项目中使用

//1.获得主队列:是一个单例, 运行在主线程, 给此队列中提交任务是串行执行的
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    //2.全局队列, 第一个参数是优先级, 根据优先级的不同是4个单例, 第二个参数是预留参数
    //全局队列是运行在子线程的, 任务是并发执行的
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"globalQueue = %@", globalQueue);
     
    dispatch_queue_t globalQueue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
NSLog(@"globalQueue2 = %@", globalQueue2);
     
    dispatch_queue_t globalQueue3 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
NSLog(@"globalQueue3 = %@", globalQueue3);
     
    dispatch_queue_t globalQueue4 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
NSLog(@"globalQueue4 = %@", globalQueue4);
     
    //3.自定义队列 运行在子线程 创建的时候指定任务是串行还是并发
    //DISPATCH_QUEUE_SERIAL  串行
    // DISPATCH_QUEUE_CONCURRENT  并发
    dispatch_queue_t customQueue = dispatch_queue_create("com.lanou", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"customQueue = %@", customQueue);
 
 
 
 
    //dispatch_async  异步执行队列, 不会等队列中的任务执行完,  就已经往下执行

    dispatch_async(dispatch_get_main_queue(), ^{
for (int i = 0; i < 10000; i++) {
NSLog(@"i = %d", i);
         }
     });
 
 
 
 

    //dispatch_sync 同步执行队列, 必须要等到队列中的任务执行完才会往下执行, 容易照成UI假死    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i = 0; i < 10000; i++) {
NSLog(@"i = %d", i);
         }
         });
 
 
 
 
    //延迟调用, 延迟几秒执行
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"Test!");
     });