概述IOS多线程

妖精的绣舞 提交于 2019-12-10 08:36:06

     在了解多线程之前,我们需要先认识一下什么是 进程线程
**进程:**是在系统中运行的一个程序,每个进程之间是独立的,每个进程均运行在其专有且受保护的内存空间内。
**线程:**一个进程想要执行任务,必须得有线程(至少一个线程),线程是进程的基本执行单元,一个进程的所有任务都必须在线程中执行。
**线程的串行:**一个线程中任务的执行是串行的,如果要在一个线程中执行多个任务,只能一个一个的按顺序执行。
     那么如何多个任务同时进行?这 便引出了我们的多线程!


一、多线程

###1.基本概念
     一个进程中可以开启多个线程,每个线程可以并发/并行执行不同的任务,多线程可以提交程序的执行效率。如下图(同时执行任务ABC):
图01

###2.多线程的原理      同一时间,CPU只能执行一个线程,只有一个线程正在执行,多线程并发执行,其实是CPU快速的在多个线程之间切换。如果CPU的切换线程的时间足够快,就会造成多线程并发执行的假象。

###3.多线程的优缺点
**优点: **(1)能适当的提高程序的执行效率
        (2)能适当的提高资源的利用率(CPU,内存)
缺点:(1)开启线程会占用一定的内存空间(主线程1M,子线程0.5M),如果开启过多的线程会占用大量的内存空间,降低程序的性能。
       (2)线程越多,CPU在调度线程上的开销就越大。 ###4.IOS中的多线程编程技术 IOS中有四种多线程的编程技术:

  • NSThread:每个Thread对象对应一个线程,线程的生命周期由我们自己管理,使用较少。
  • NSOperation:面向对象的线程技术,基于GCD来实现,生命周期由系统管理,经常使用。
  • GCD:基于C语言的框架,可以充分利用多核,是苹果推荐使用的多线程技术,生命周期由系统管理,经常使用。

以上三种编程技术由上至下,抽象度层次是从低到高的,抽象度越高使用越简单,也是Apple最推荐使用的。

二、NSThread

NSThread有二种创建方式

//实方法例
NSThread *thread = [[NSThread alloc]initWithTarget:self self selector:@selector(threadMethod ) object:nil];

[thread start];

//类方法
[NSThread detachNewThreadSelector: @selector (threadMethod ) toTarget:self withObject:nil];

参数解析:
selector :线程执行的方法,只能有一个参数,而且不能有返回值
target :selector消息发送的对象
argument:传输给target的唯一参数,也可以是nil

三、NSOperation

      NSOperation的使用有两种方式:一种是使用定义好的两个类:NSInvocationOperation和NSBlockOperation,另一种是继承NSOperation。

1.NSInvocationOperation

创建 NSInvocationOperation

    //直接执行会在主线程中顺序执行

    NSInvocationOperation * operation_1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run_A) object:nil];

    [operation_1 start];      // 启动任务

    // 创建一个队列,默认就是并行队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 设置当前最大的执行数,可以控制是并行还串行,为1时就是串行
    queue.maxConcurrentOperationCount = 1;
    
    // 将任务添加到队列中任务就自动执行了
    [queue addOperation: operation_1];

2.NSBlockOperation

创建NSBlockOperation

// 至少会有一个任务在主线程中执行,其他任务会被放到其他线程中执行
    NSBlockOperation *blockOperation_1 = [NSBlockOperation blockOperationWithBlock:^{
       
        [self run_A];
    }];
    [blockOperation_1 addExecutionBlock:^{
        
        [self run_B];
    }];

    [opertion start];


###3.继承 NSOperation

#import <Foundation/Foundation.h>
@interface CustomOperation :NSOperation

@end


#import"CustomOperation.h"
-(void)main{
   
       NSLog(@"%@",[NSTread currentThread]);
}

##四、GCD       GCD是Apple开发的一个多核编程的解决方法。该方法在MAC OS X10.6首次推出,随后引用到IOS4.0中。GCD是一个替代诸如:NSThread,NSOperationQueue,NSInvocationOperation等技术的很高效和强大的技术。

      GCD队列:分为串行队列(DISPATCH_QUEUE_SERIAL)和并⾏队列(DISPATCH_QUEUE_CONCURRENT)。

** 系统提供的GCD队列:**
**主队列:**使用 dispatch_get_main_queue 函数来获取和主线程关联的串行队列
**全局队列:**系统提供的一个全局并行的队列,使用 dispatch_get_global_queue 函数获取

系统提供的dispatch方法:

//主线程执行一次
dispatch_async(dispatch_get_main_queue(), ^{
   //task     
});  
  
//后台执行  
dispatch_async (dispatch_get_global_queue(0,0), ^{
    //task
})  
  
//执行一次  
static dispatch_once _t onceToken;  
dispatch_once(& onceToken,^{  
    //task
});  
  
//延迟执行  
int sec = 2;   
dispatch_after(dispatch_time (DISPATCH_TIME_NOW , (int64_t)  
(sec * NSEC_PER_SEC)), dispatch_get_main_queue(),^{    
//task        
})

###1.同步
      同步任务:dispatch_sync,会阻塞后面的任务,必需当前任务完成后才能执行下一个

     dispatch_sync(dispatch_get_main_queue(), ^{
     
     self.imagView_1.image = [self downloadImage_one];
     
     });

###2.异步
      异步执行:dispatch_async,不会阻塞后面的任务,任务会马上返回下一个任务不需要等待,当这个任务完成后会通知主线程.

     dispatch_async(dispatch_get_main_queue(), ^{
     
     [self run_D];
     });
     
     dispatch_async(dispatch_get_main_queue(), ^{
     
     [self run_B];
     });
     
     dispatch_async(dispatch_get_main_queue(), ^{
     
     [self run_C];
     });

      dispatch_get_main_queue() 获取主队列,主队列中的任务都会在主线程中执行, 是一个串行队列
###3.串行
      自定义的串行队列,中异步执行任务,队列会把任务放到一个新的线程中按顺序执行

    dispatch_queue_t serialQueue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
    dispatch_async(serialQueue, ^{
        
        [self run_A];
    });
    
    dispatch_async(serialQueue, ^{
        
        [self run_B];
    });
    
    dispatch_async(serialQueue, ^{
        
        [self run_C];
    });
     
    */

###4.并行
      dispatch_get_global_queue() 全局队列,是一个并行队列,可以将队列中的任务放到不同的线程中执行

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
     
         [self run_A];
     });
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
     
         [self run_B];
     });
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
     
         [self run_C];
     });

任务执行的优先级

        DISPATCH_QUEUE_PRIORITY_HIGH 2   //最高
        DISPATCH_QUEUE_PRIORITY_DEFAULT 0 //中等(默认)
        DISPATCH_QUEUE_PRIORITY_LOW (-2) //低
        DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN //后台执行

      如果在并行队列中同步执行任务,那么这些任务都会在主线程中按顺序执行,也就没有并发性了。

     dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
     
     [self run_A];
     });
     dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
     
     [self run_B];
     });
     dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
     
     [self run_C];
     });

      自定义的并行队列中异步执行任务,队列会把任务放到不同的线程中执行

     dispatch_queue_t concurrentlQueue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
     dispatch_sync(concurrentlQueue, ^{
     
     [self run_A];
     });
     
     dispatch_sync(concurrentlQueue, ^{
     
     [self run_B];
     });
     
     dispatch_sync(concurrentlQueue, ^{
     
     [self run_C];
     });  

##五、NSOperation与GCD的区别
**1、底层实现:**GCD的底层是用C来实现的,NSOperation底层从ios4开始也是用的GCD来实现的。
**2、取消任务:**在NSOperationQueue中,我们可以随时取消已经设定要准备执行的任务(当然,已经开始的任务就无法阻⽌了),而GCD没法停止已经加入queue的block(其实是有的,但需要许多复杂的代码)。
** 3、依赖关系:**NSOperation能够方便地设置依赖关系,我们可以让⼀个Operation依赖于另一 个Operation,这样的话尽管两个Operation处于同一个并行队列中,但前者会直到后者执行完毕后再执⾏。
**4、监听任务的执行情况:**我们能将KVO应用在NSOperation中,可以监听一个Operation是否完成或取消,这样子能比GCD更加有效地掌控我们执行的后台任务。
**5、优先级:**在NSOperation中,我们能够设置NSOperation的priority优先级,能够使同一个并行队列中的任务区分先后地执行,⽽在GCD中,我们只能区分不同任务队列的优先级,如果要区分block任务的优先级,也需要大量的复杂代码。
**6、代码复⽤:**我们能够对NSOperation进行继承,在这之上添加成员变量与成员方法,提⾼整个代码的复⽤度,这比简单地将block任务排⼊入执⾏队列更有⾃由度,能够在其之上添加更多⾃定制的功能。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!