iOS中的四个多线程解决方案

主线程:线程是进程的基本执行单元,一个iOS程序运行后,默认会开启1条线程,称为“主线程”又叫“UI线程”
主线程的主要作用
1.显示\刷新UI界面
2.处理UI事件(比如点击事件、滚动事件、拖拽事件等)

iOS有四个多线程解决方案

一. Pthreads

这是一套在很多操作系统上都通用的多线程API,所以移植性很强(然并卵),当然在 iOS 中也是可以的。不过这是基于 c语言
的框架,使用起来这酸爽!感受一下

1.包含头文件

#import <pthread.h>

2.创建线程,并执行任务

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    pthread_t thread;
    //创建一个线程并自动执行
    pthread_create(&thread, NULL, start, NULL);
}

void *start(void *data) {
    NSLog(@"%@", [NSThread currentThread]);

    return NULL;
}

到了这里也许你还会问 到底这个线程到底操作了什么 别急 跟着小龙哥看下一个

二.NSThread

经过苹果封装后的,并且完全面向对象的。所以你可以直接操控线程对象,非常直观和方便。但是,它的生命周期还是需要我们手动管理,所以这套方案也是偶尔用用,比如 [NSThread currentThread],它可以获取当前线程类,你就可以知道当前线程的各种属性,用于调试十分方便。下面来看看它的一些用法。

1.创建启动异步

  // 创建
  NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:nil];

  // 启动
  [thread start];

2.创建启动同步完成

 1.直接创建并自动启动
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:nil];
  2.使用 NSObject 的方法创建并自动启动
  [self performSelectorInBackground:@selector(run:) withObject:nil];

注意:

Note: The performSelector: method and related selector-invoking methods are not imported in Swift because they are inherently unsafe.
因为安全问题 苹果在swift中取消了performSelector这个方法

3.NSThread常用方法

除了创建启动外,NSThread 还以很多方法,下面我列举一些常见的方法,当然我列举的并不完整,更多方法大家可以去类的定义里去看。

//取消线程
- (void)cancel;

//启动线程
- (void)start;

//判断某个线程的状态的属性
@property (readonly, getter=isExecuting) BOOL executing;
@property (readonly, getter=isFinished) BOOL finished;
@property (readonly, getter=isCancelled) BOOL cancelled;

//设置和获取线程名字
-(void)setName:(NSString *)n;
-(NSString *)name;

//获取当前线程信息
+ (NSThread *)currentThread;

//获取主线程信息
+ (NSThread *)mainThread;

//使当前线程暂停一段时间,或者暂停到某个时刻
+ (void)sleepForTimeInterval:(NSTimeInterval)time;
+ (void)sleepUntilDate:(NSDate *)date;

三.GCD

Grand Central Dispatch 主要的线程优化技术

他最伟大的优点在于它会自动管理线程的生命周期(创建线程、调度任务、销毁线程)使用起来非常方便

1.如何使用GCD

首先我们要明白两个非常重要的概念

  • 任务:即操作,你想要干什么,说白了就是一段代码,在 GCD 中就是一个 Block,所以添加任务十分方便。任务有两种执行方式: 同步执行 和 异步执行,他们之间的区别是 是否会创建新的线程。

同步(sync) 和 异步(async) 的主要区别在于会不会阻塞当前线程,直到 Block 中的任务执行完毕!
如果是 同步(sync) 操作,它会阻塞当前线程并等待 Block 中的任务执行完毕,然后当前线程才会继续往下运行。
如果是 异步(async)操作,当前线程会直接往下执行,它不会阻塞当前线程。

  • 队列:用于存放任务。一共有两种队列, 串行队列 和 并行队列

2.创建队列

  • 1.主队列
dispatch_queue_t queue = ispatch_get_main_queue();
  • 自己创建的队列:

自己可以创建 串行队列, 也可以创建 并行队列。第二个参数用来表示创建的队列是串行的还是并行的

  • 2.1创建串行队列

DISPATCH_QUEUE_SERIAL 或 NULL 表示

  • 2.2创建并行队列

-DISPATCH_QUEUE_CONCURRENT

 //串行队列
  dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", NULL);
  dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_SERIAL);
  //并行队列
  dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_CONCURRENT);
3.全局并行队列

只要是并行任务一般都加入到这个队列。这是系统提供的一个并发队列。

  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

3.创建任务

  • 同步任务:会阻塞当前线程 (SYNC)
  dispatch_sync(<#queue#>, ^{
      //code here
      NSLog(@"%@", [NSThread currentThread]);
  });
  • 异步任务:不会阻塞当前线程 (ASYNC)
  dispatch_async(<#queue#>, ^{
      //code here
      NSLog(@"%@", [NSThread currentThread]);
  });

4.队列组

队列组可以将很多队列添加到一个组里,这样做的好处是,当这个组里所有的任务都执行完了,队列组会通过一个方法通知我们。下面是使用方法,这是一个很实用的功能。

//1.创建队列组
dispatch_group_t group = dispatch_group_create();
//2.创建队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//3.多次使用队列组的方法执行任务, 只有异步方法
//3.1.执行3次循环
dispatch_group_async(group, queue, ^{
    for (NSInteger i = 0; i < 3; i++) {
        NSLog(@"group-01 - %@", [NSThread currentThread]);
    }
});

//3.2.主队列执行8次循环
dispatch_group_async(group, dispatch_get_main_queue(), ^{
    for (NSInteger i = 0; i < 8; i++) {
        NSLog(@"group-02 - %@", [NSThread currentThread]);
    }
});

//3.3.执行5次循环
dispatch_group_async(group, queue, ^{
    for (NSInteger i = 0; i < 5; i++) {
        NSLog(@"group-03 - %@", [NSThread currentThread]);
    }
});

//4.都完成后会自动通知
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    NSLog(@"完成 - %@", [NSThread currentThread]);
});

四 NSOperation & NSOperationQueue

NSOperation 是苹果公司对 GCD 的封装,完全面向对象,所以使用起来更好理解。 大家可以看到 NSOperation 和
NSOperationQueue 分别对应 GCD 的 任务 和 队列 。操作步骤也很好理解

五 NSOperation & NSOperationQueue

我们进行完多线程操作或 都需要回到主线程 接下来 就是讲到上面的四种方法是如何回到主线程(UI线程逻辑中的)

5.1 NSThread

[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:NO];

5.2 GCD

dispatch_async(dispatch_get_main_queue(), ^{

});

5.3 NSOperationQueue

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

}];
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值