iOS开发 多线程和GCD

多线程


多线程的三种方式:1.thread 2.OPerationQuete 3.NSObject

多线程:程序:有源代码生成可执行应用(.exe,.app)

               进程:一个正在运行的程序可以看做是一个进程,进程拥有独立运行所需的全部资源

               线程:多线程是为了系统可以运行多个程序,多线程是为了app可以运行多个任务

进程拥有独立的资源,线程不会

一个程序有一个或多个线程组成,进程只负责资源的调度,线程才是程序真正执行单元,负责代码执行

一个程序至少有一个线程,称为主线程,程序中只有一个主线程的程序,叫单线程程序;运行中会有多个线程的程序,叫多线程程序

子线程:iOS中允许用户开辟新线程,相对于主线程来说这些都是子线程

主线程:负责界面展现和刷新,旧版网络请求,数据库的请求,这些代码只能顺序执行,不能并发执行,

多线程的原理:CPU只能处理一条线程,只有一个线程在工作执行,多线程并发同时执行,其实就是CPU在多条线程之间调度切换,如果CPU调度线程的时间足够快,就造成多条线程并发执行的假象

思考:如果线程非常非常多,会发生什么情况?
     CPU会在N多线程之间调度,CPU会累死,消耗大量的CPU资源
     每条线程被调度执行的频次会降低(线程的执行效率降低)

3.多线程的优缺点
     多线程的优点
     能适当提高程序的执行效率
     能适当提高资源利用率(CPU、内存利用率)

     多线程的缺点
     开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能
     线程越多,CPU在调度线程上的开销就越大
     程序设计更加复杂:比如线程之间的通信、多线程的数据共享
     4.多线程在iOS开发中的应用
     主线程:一个iOS程序运行后,默认会开启1条线程,称为“主线程”或“UI线程”
     主线程的主要作用
    1. 显示\刷新UI界面
    2. 处理UI事件(比如点击事件、滚动事件、拖拽事件等)
    3.主线程的使用注意:别将比较耗时的操作放到主线程中。
    4. 耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种“卡”的坏体验



在storyboard中添加一个按钮,再拖拽点击事件
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    }
#pragma mark          thread方式;
- (IBAction)CountAction:(id)sender {
/*
    //开启多线程
    //方式一:需要手动在合适时机开启线程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadAction) object:nil];
    thread.name = @"text";
    //手动开启;
 [thread start];
    
    //方式二:直接就开启线程,不需要手动启动
    //[NSThread detachNewThreadSelector:@selector(threadAction) toTarget:self withObject:nil];
    NSLog(@"%@",[NSThread currentThread]);
    */
#pragma mark          NSOperationQueue;
/*
      NSOperationQueue:操作队列
     会根据操作的数量分配合适的线程去进行操作,通常与NSOperation进行配合操作,用户可以不用关心多线程,只需将每个多线程的任务做成NSOperation,然后放到队列中。队列会自动创建合适的线程
     
     NSOperation:操作
     NSOperation:本身并没有子线程,只是一个操作,多线程的是Queue
     NSOperation:是一个抽象类,不能直接使用,一般是使用他的子类NSBlockOperation,NSInvocationOperation
     */
/*
//创建操作
    NSInvocationOperation *op1 =[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationAction) object:nil];
    //
    //[op1 start];
    //创建操作
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"block:%@",[NSThread currentThread]);
       // [op2 start];
    } ];
//    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
//        NSLog(@"block2:%@",[NSThread currentThread]);
//    }];
//
//    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
//        NSLog(@"block3:%@",[NSThread currentThread]);
//    }];
//
    //创建操作队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    //每个操作可以设置优先级
    op1.queuePriority = NSOperationQueuePriorityHigh;
    //queue可以设置最大并行线程数
    //当最大线程数设置为1的时候,是串行(可以保证任务是串行的)但是不能保证线程好使一样的
    queue.maxConcurrentOperationCount = 3;
    [op1 addDependency:op2];//添加依赖,当第二个执行结束的时候
    [queue addOperation:op1];
    [queue addOperation:op2];
//    [queue addOperation:op3];
//    [queue addOperation:op4];
     */
 
#pragma mark          NSObject
    [self performSelectorInBackground:@selector(threadAction) withObject:nil];
    
    NSLog(@"%@",[NSThread currentThread]);
    
        }
//NSOperationQueue;的点击事件
- (void)invocationAction{
    NSLog(@"invocation:%@",[NSThread currentThread]);
}


- (void)threadAction{
    //输出1-1000000
    for (int i = 0; i < 1000000; i++) {
       // NSLog(@"%d",i);
    }
    NSLog(@"%@",[NSThread currentThread]);
}



@end


GCD

全称:Grand Central Dispatch :是苹果公司开发的,以优化应用程序支持多核和其他对称多系统的系统
     GCD是函数级编程,所以更高效,功能更强大
     
     任务:
     具有一定功能的代码段,一般是一个Block或者函数
     分发队列:
     GCD以队列的方式进行工作,FIFO(先进先出)。
     GCD会根据分发队列的不同,创建合适数量的线程执行队列中的任务
     
     队列两种:
     一种是串行队列:1.系统提供的串行队列 2.自定义串行队列
     一种是并行队列:1.系统提供的串行队列 2.自定义串行队列




在storyboard中建立几个button,并拖拽点击事件

//采用系统方式添加串行任务
- (IBAction)SerialMainAction:(id)sender {
    //系统提供的串行队列其实就是主线程队列
    //1.拿到主线程队列
    dispatch_queue_t main = dispatch_get_main_queue();
    //2.给主线程队列添加任务
    
    dispatch_async(main, ^{
        NSLog(@"我是主线程队列第1个任务%@",[NSThread currentThread]);
    });
    dispatch_async(main, ^{
        NSLog(@"我是主线程队列第2个任务%@",[NSThread currentThread]);
    });
    dispatch_async(main, ^{
        NSLog(@"我是主线程队列第3个任务%@",[NSThread currentThread]);
    });
    dispatch_async(main, ^{
        NSLog(@"我是主线程队列第4个任务%@",[NSThread currentThread]);
    });
    dispatch_async(main, ^{
        NSLog(@"我是主线程队列第5个任务%@",[NSThread currentThread]);
    });
    
}

//采用自定义的方式添加串行任务
- (IBAction)SerialBySelfAction:(id)sender {
    //创建串行队列
    dispatch_queue_t serialQueue = dispatch_queue_create("yan5", DISPATCH_QUEUE_SERIAL);
    //添加任务
    dispatch_async(serialQueue, ^{
        NSLog(@"自定义串行任务第一个%@",[NSThread currentThread]);
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"自定义串行任务第二个%@",[NSThread currentThread]);
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"自定义串行任务第三个%@",[NSThread currentThread]);
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"自定义串行任务第四个%@",[NSThread currentThread]);
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"自定义串行任务第五个%@",[NSThread currentThread]);
    });
}
//通过系统方式创建并行队列
- (IBAction)GlobalAction:(id)sender {
    //拿到并行队列
    dispatch_queue_t globle = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //添加任务
    dispatch_async(globle, ^{
        NSLog(@"系统并行的第一个任务:%@",[NSThread currentThread]);
    });
    dispatch_async(globle, ^{
        NSLog(@"系统并行的第二个任务:%@",[NSThread currentThread]);
    });
    dispatch_async(globle, ^{
        NSLog(@"系统并行的第三个任务:%@",[NSThread currentThread]);
    });
    dispatch_async(globle, ^{
        NSLog(@"系统并行的第四个任务:%@",[NSThread currentThread]);
    });
    dispatch_async(globle, ^{
        NSLog(@"系统并行的第五个任务:%@",[NSThread currentThread]);
    });

    
}
//自定义方式创建并行队列
- (IBAction)ConcurrentAction:(id)sender {
    //拿到并行队列
    dispatch_queue_t concurrent = dispatch_queue_create("1146", DISPATCH_QUEUE_CONCURRENT);
 dispatch_async(concurrent, ^{
       NSLog(@"自定义并行队列第一个任务:%@",[NSThread currentThread]);
 });
    dispatch_async(concurrent, ^{
        NSLog(@"自定义并行队列第二个任务:%@",[NSThread currentThread]);
    });
    dispatch_async(concurrent, ^{
        NSLog(@"自定义并行队列第三个任务:%@",[NSThread currentThread]);
    });
    dispatch_async(concurrent, ^{
        NSLog(@"自定义并行队列第四个任务:%@",[NSThread currentThread]);
    });
    dispatch_async(concurrent, ^{
        NSLog(@"自定义并行队列第五个任务:%@",[NSThread currentThread]);
    });

}
//让任务延迟一段时间执行
- (IBAction)DelayAction:(id)sender {
    double time = 6;
    //第一个参数从什么时候开始延迟
    //第二个参数延迟多长时间
    dispatch_time_t DTime = dispatch_time(DISPATCH_TIME_NOW, time * NSEC_PER_SEC);
    //拿到队列
    dispatch_queue_t global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//拿到全局队列
    //添加延时任务
    dispatch_after(DTime, global, ^{
        NSLog(@"我被执行");
    });
    
    
}
//重复执行一个任务

//重复执行任务只能跟串行一起用
- (IBAction)RepeatAction:(id)sender {
    //拿到全局队列
    dispatch_queue_t globel = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    
    NSArray *arr = @[@"阿猫",@"阿狗",@"阿彪"];
    //添加重复任务
    //1参数重复多少次2参数放在哪一个队列里 3参数任务的Block块
    dispatch_apply(arr.count, globel, ^(size_t size) {
        NSLog(@"arr[%zu]:%@",size,arr[size]);
    });
}
//    让线程在程序运行期间只运行一次
- (IBAction)OnlyYouAction:(id)sender {
//创建一个静态的进程
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        NSLog(@"一次就好");
    });
    
    
}

//线程之间的通信

/*
1.子线程中使用主线程的数据
2.主线程中使用子线程的数据
*/






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值