iOSh中多线程的使用

一、什么是多线程

1.    每一个进程都是一个应用程序,都有独立的内存空间,一般来说一个应用程序存在一个进程,但也有多个进程的情况。

2.    同一个进程中的线程共享内存中内存和资源。

3.    线程处理方式通过堆栈的形式来处理的,先进后出。放在堆内存里面管理

4.    每一个程序如果要运行,它都会创建一个主线程(每个程序都有一个主线程),程序启动时创建(调用main来启动)。

5.    每一个程序只有一个进程,但是在一个进程里面有多个线程。(也有1个线程的情况),进程相当于是一个容器,在这个容器里面装了多个进程,线程是在运行的,它可以去调用函数调用代码。

6.    主线程的生命周期和应用程序绑定的,程序退出(结束)时,主线程也就停止了。

7.    多线程技术表示,一个应用程序有多个线程,使用多线程能够提供CPU的使用率,防止主线程堵塞

8.    任何有可能堵塞主线程的任务不要在主线程执行(访问网络)

9.    进入后台时,主线程就会被挂起(程序退出时,主线程会被退出)

10.    每个线程相当于是一个路径,多线程相当于是多个分支的路径,由主路径(主线程)分支出来

11.    4和CPU就是多线程任务同时处理的


二、使用多线程的目的是什么

1. 引入多线程的主要目的是对大量任务进行有序的管理。通过多个任务的混合使用,可以更有效地利用计算机资源,避免主线程阻塞。

2. 比如在加载网络图片的时候,如果加载网络图片的过程用主线程来加载就会导致主线程堵塞,因为图片正在加载过程中正在使用主线程,这个时候无法操作其他了,所以这个时候可以让加载图片的操作让子线程去异步加载。


三、ios中有哪几种多线程方式

1. NSObject中的performSelectorInBackground方法

//通过NSObject的performSelectorInBackground多线程方法来异步请求图片,此方法最为简单。downLoadImage是后台(子线程)执行的方法
[self performSelectorInBackground:@selector(downLoadImage) withObject:nil];

2. NSThread

// 优点:在所有的多线程实现方式中最轻量级,可以按照需求任意控制thread对象 即:线程的加锁等操作
// 缺点:控制太繁琐 不能自己控制线程安全
    // NSThread 的一个对象 就代表一个线程
    NSThread *thread = [[NSThread alloc]initWithTarget:selfselector:@selector(btnUpClicked:)object:nil];
    [thread start];

3. NSOperationQueue

    // 优点:能够自己管理 线程安全 能够合理的安排线程 降低系统的开销 提高对线程的利用率
    // 缺点:可读性差 写起来比较繁琐

    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    // 设置最大并发数
    [queue setMaxConcurrentOperationCount:2];
    NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downLoadImage) object:nil];
    [queue addOperation:op];

4. GCD(比较常用,多核CPU的情况下建议使用此方式)

4.1  一般用法

    // GCD 是基于队列的 多线程实现方式
    // 队列的类型
    // 1.并行: 多个任务同时执行 Concurrent
    // 2.串行: 依次执行任务(同一事件只执行一个任务) Serial
     
    // 自己创建一个队列
    // 参数1:给队列起个名字
    // 参数2:选择队列的类型 DISPATCH_QUEUE_CONCURRENT(串行) 
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    // 使用队列  
    // 参数1: 在哪个队列执行代码  
    // 参数2: 要执行的代码  
    dispatch_async(queue, ^{
        [self downLoadImage];  //回调
    });

4.2 高级用法

  // 系统定义了5个队列
    // 1. 一个串行队列  主队列作用 : 管理主线程的相关事务
     
    // 获得主队列
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    // 在主队列执行任务
//    dispatch_async(mainQueue, ^{
//        [self btnUpClicked:nil];
//    });
     
     
    // 2. 4个并行队列 (并行队列)
    // 参数1: 选择队列的优先级
    // 参数2: 给未来使用 一般填0
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//    dispatch_async(globalQueue, ^{
//        [self btnUpClicked:nil];
//    });
     
    // 高端使用
    // 1.全局队列获取数据 回到主队列将数据加载到视图上
//    dispatch_async(globalQueue, ^{
//       
//        // 全局队列(子线程)获取数据
//        NSString *str = @"htt://www.baidu.com";
//        NSURL *url = [NSURL URLWithString:str];
//        
//        NSData *data = [NSData dataWithContentsOfURL:url];
//        UIImage *image = [UIImage imageWithData:data];
//        
//        // 返回主线程 加载UI/更新UI
//        dispatch_async(mainQueue, ^{
//           
//            UIImageView *imageView = [[UIImageView alloc] init];
//            // 给视图赋值
//            imageView.image = image;
//            
//        });
//    });
     
    // 2.一段代码只执行依次
    // 大部分的时候 都在单例方法中使用
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"只执行依次");
    });
     
    // 3.一段代码执行多次 (全局队列有效)
    // 参数1: 执行多少次
    // 参数2: 在哪个队列有效
    // 参数3: 要执行的内容
    dispatch_apply(4, globalQueue, ^(size_t a) {
        NSLog(@"%zu", a);
    });
     
    // 4.定时
    // 参数1: 间隔几秒
    // 参数2: 执行的内容
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"=====");
    });


四、代码示例

//加载网络图片时候的例子

- (void)loadImageQueueInit
{
    //*****************1. 通过队列多线程来异步加载图片*****************
    /*
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downLoadImage) object:nil];
    [queue addOperation:op];
     */
    
     //**********2. 通过NSObject的performSelectorInBackground多线程方法来异步请求图片**********//
     //[self performSelectorInBackground:@selector(downLoadImage) withObject:nil];
     
    
    //***************3. 通过GCD的方式创建一个新的线程来异步加载图片***************//
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        [self downLoadImage];  //回调
    });
}

- (void)downLoadImage
{
    NSURL  *imageURL = [NSURL URLWithString:self.figureurl];
    imageData = [NSData dataWithContentsOfURL:imageURL];
    [_pathCover setAvatarImage:[UIImage imageWithData:imageData]];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值