iOS--多线程具体总结(OC&Swift)

整理一下 iOS 开发中几种多线程方案,以及其使用方法和注意事项。当然也会给出几种多线程的案例,在实际使用中感受它们的区别。使用 Swift 和 Objective-C 两种语言讲解

在 iOS 中其实目前有 4 套多线程方案,他们分别是:

1,Pthreads
2,NSThread
3,GCD
4,NSOperation & NSOperationQueue

Pthreads

POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。在类Unix操作系统(Unix、Linux、Mac OS X等)中,都使用Pthreads作为操作系统的线程。
简单地说,这是一套在很多操作系统上都通用的多线程API,所以移植性很强,当然在 iOS 中也是可以的。

Objective-C
包含头文件

#import <pthread.h>
然后创建线程,并执行任务


- (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;
}

打印输出:

{number = 2, name = (null)}
看代码就会发现他需要 c语言函数,你需要手动处理线程的各个状态的转换即管理生命周期,这段代码虽然创建了一个线程,但并没有销毁。

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

创建并启动
先创建线程类,再启动

Objective-C

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

  // 启动
  [thread start];

Swift

  //创建
  let thread = NSThread(target: self, selector: "run:", object: nil)

  //启动
  thread.start()

创建并自动启动

Objective-C

  [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:nil];

Swift

  NSThread.detachNewThreadSelector("run:", toTarget: self, withObject: nil)

使用 NSObject 的方法创建并自动启动

Objective-C

  [self performSelectorInBackground:@selector(run:) withObject:nil];

Swift
苹果认为 performSelector: 不安全,所以在 Swift 去掉了这个方法。
Note: The performSelector: method and related selector-invoking methods are not imported in Swift because they are inherently unsafe.
其他方法
除了创建启动外,NSThread 还以很多方法,下面我列举一些常见的方法,当然我列举的并不完整,更多方法大家可以去类的定义里去看。

Objective-C
//取消线程
- (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;

Swift
Swift的方法名字和OC的方法名都一样

GCD
Grand Central Dispatch,它是苹果为多核的并行运算提出的解决方案,所以会自动合理地利用更多的CPU内核(比如双核、四核),最重要的是它会自动管理线程的生命周期(创建线程、调度任务、销毁线程),完全不需要我们管理,我们只需要告诉干什么就行。同时它使用的也是 c语言,不过由于使用了 Block(Swift里叫做闭包),使得使用起来更加方便,而且灵活。

任务和队列
在 GCD 中,加入了两个非常重要的概念: 任务 和 队列。

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

同步执行:只要是同步执行的任务,都会在当前线程执行,不会另开线程。

异步执行:只要是异步执行的任务,都会另开线程,在别的线程执行。

这里说的并不准确,同步(sync) 和 异步(async) 的主要区别在于会不会阻塞当前线程,直到 Block 中的任务执行完毕!
如果是 同步(sync) 操作,它会阻塞当前线程并等待 Block 中的任务执行完毕,然后当前线程才会继续往下运行。
如果是 异步(async)操作,当前线程会直接往下执行,它不会阻塞当前线程。
队列:用于存放任务。一共有两种队列, 串行队列 和 并行队列。

串行队列 中的任务会根据队列的定义 FIFO 的执行,一个接一个的先进先出的进行执行。

放到串行队列的任务,GCD 会 FIFO(先进先出) 地取出来一个,执行一个,然后取下一个,这样一个一个的执行。
并行队列 中的任务 根据同步或异步有不同的执行方式。

放到并行队列的任务,GCD 也会 FIFO的取出来,但不同的是,它取出来一个就会放到别的线程,然后再取出来一个又放到另一个的线程。这样由于取的动作很快,忽略不计,看起来,所有的任务都是一起执行的。不过需要注意,GCD 会根据系统资源控制并行的数量,所以如果任务很多,它并不会让所有任务同时执行。
虽然很绕,但请看下表:

同步执行 异步执行
串行队列 当前线程,一个一个执行 其他线程,一个一个执行
并行队列 当前线程,一个一个执行 开很多线程,一起执行
创建队列
主队列:这是一个特殊的 串行队列。什么是主队列,大家都知道吧,它用于刷新 UI,任何需要刷新 UI 的工作都要在主队列执行,所以一般耗时的任务都要放到别的线程执行。

//Objective-C

  dispatch_queue_t queue = ispatch_get_main_queue();

//Swift

  let queue = ispatch_get_main_queue()

自己创建的队列:凡是自己创建的队列都是 串行队列。 其中第一个参数是标识符,用于 DEBUG 的时候标识唯一的队列,可以为空。


第二个参数用来表示创建的队列是串行的还是并行的,传入 DISPATCH_QUEUE_SERIAL 或 NULL 表示创建串行队列。传入 DISPATCH_QUEUE_CONCURRENT 表示创建并行队列。
//Objective-C
//串行队列

  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);

//Swift

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值