iOS多线程基础(一)

多线程在开发中是一个比较重要的概念,在我们开发程序提高性能方面起到很大的作用,什么是多线程?我举一个很直观的例子,例如我们的程序执行过程就像公路上行驶的小汽车,一条车道只能允许一辆小汽车通过,为了在同一时间允许多辆小汽车通过,人们就设计了多条车道,这样一个路口同一时间通过的汽车数就多了。同理,程序在执行的过程中有多个任务需要处理,如何在最短的时间内,高效的完成任务呢?就设计了多线程。要了解多线程我们必须知道几个概念,什么是进程?什么是线程?

什么是进程?
  • 进程是指在系统中正在运行的一个应用程序,每个进程之间是相互独立的,系统会给每个进程分配属于自己的内存空间
什么是线程?
  • 一个进程想要执行任务,必须得有线程,每个进程至少要有一个线程,进程的所有任务都在线程中执行,线程中的任务执行是串行的,同一时间内一个线程只能执行1个任务。
什么是多线程?
  • 多线程就是指一个进程中可以开启多条线程,可以同时执行不同的任务。多线程可以提高程序的执行效率。
多线程在iOS中的使用
  • 我们启动一个iOSAPP的时候,系统默认会开启一个线程,我们称为主线程或者UI线程,它主要的作用就是刷新页面处理和用户交互,但是如果我们开发中如果将一些比较耗时的操作放在主线程中,这种容易使我们的应用非常卡顿,影响用户体验。所以平时我们开发人员在开发的过程中,会将一些耗时的操作放在子线程中执行,例如网络请求、加载大图片等操作。
  • 开发中我们常用的三种开始多线程的方法:
    (1) NSThread:苹果中NS开头的类肯定是面向对象的,使用简单,可直接操作对象。
    (2)GCD:这个是非常强大的,苹果推荐使用,充分利用设备多核,平时开发中使用也最多,理解使用步骤,操作起来也是很简单的。之后会详细介绍使用的方式。
    (3)NSOperation:这个是基于GCD,更加面向对象了,比GCD更加简单了。
基本原理我们都了解了,下面直接上代码,学习如何使用NSThread开启线程。
  • 创建线程,然后启动线程。只需2步就OK了
          // 创建线程
         NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"bobo"];
         // 启动线程
         [thread start];
    - (void)run:(NSString *)param
    {
       //[NSThread currentThread] 打印当前线程
         for (NSInteger i = 0; i<100; i++) {
                NSLog(@"-----run-----%@--%@", param, [NSThread currentThread]);
     }
    }
    
  • NSThread其他方式开始线程
    - (void)createThread3
     {
         [self performSelectorInBackground:@selector(run:) withObject:@"jack"];
     }
     - (void)createThread2
     {
          [NSThread detachNewThreadSelector:@selector(run:) toTarget:self  withObject:@"rose"];
     }
    
  • 线程的状态一般就2种,就绪状态(等待执行),执行状态(正在执行)。
         [NSThread sleepForTimeInterval:2]; // 让线程睡眠2秒(阻塞2秒)
         [NSThread sleepUntilDate:[NSDate distantFuture]];//distantFuture 遥远的未来,如果写上这句,那么程序执行到这里就直接睡死了,下面的代码不会在执行了。
         [NSThread exit]; // 直接退出线程
         
    
线程的安全

在多线程的运作之下,会出现多个任务共享同一资源,这样会造成数据错乱的问题。例如多个窗口买票,三个窗口同一时间都卖同一个座位的票,票只有一张到底怎么分配,所以这样会出现数据错乱的问题,为了解决这个问题,我们使用互斥锁去解决,同一时间只许一个人操作数据,将数据加锁,当前这个人没有解锁之前,别人无法访问资源。同时我们在使用锁的时候注意下,不能出现死锁的现象,死锁就是连个进程访问同一资源而陷入了相互等待。苹果给我们提供了一个关键字@synchronized处理加锁问题。代码如下
```
@synchronized(self) {
// 先取出总数
NSInteger count = self.ticketCount;
if (count > 0) {
self.ticketCount = count - 1;
NSLog(@"%@卖了一张票,还剩下%zd张", [NSThread currentThread].name, self.ticketCount);
} else {
NSLog(@“票已经卖完了”);
break;
}
}

线程间的通信

平时我们在子线中处理一些耗时的操作,处理完之后,我们拿到数据展示到页面上。处理UI只能在主线程中操作。所以如何从子线程中切回到主线程中呢?以下三种方式都可以回到主线程(MainThread)需要注意下。
```
// 回到主线程,显示图片方式1
[self.imageView performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:NO];
/ 回到主线程,显示图片方式2
[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
/ 回到主线程,显示图片方式3
[self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值