- 主线程
一个iOS程序运行后,默认会开启一条线程,称为主线程或UI线程
-
主线程的主要作用
显示、刷新UI界面
处理UI事件(比如点击事件,拖拽事件,滚动事件) 主线程的使用注意
别将比较耗时的操作放入主线程
耗时操作会卡住主线程
如果将耗时操作放入子线程(后台线程)
- 多线程的实现方案
第一种我们只需要了解即可
-
NSThread
- 第一种创建线程的方法
// 1、创建线程 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadAction:) object:@"jack"]; thread.name = @"myThread"; // 2、启动线程 [thread start];
- 第二种创建方式
// 简单的使用线程,不能创建名字
[NSThread detachNewThreadSelector:@selector(threadAction:) toTarget:self withObject:@"lxy"];
- 第三种创建方式
// 隐式创建线程
[self performSelectorInBackground:@selector(threadAction:) withObject:@"lxy"];
- 互斥锁
@synchronized(锁对象)一般就用self(或者叫做线程同步)
互斥锁的使用前提
> 多条线程抢占同一条资源
优缺点
> 优点
能有效防止因多条线程抢夺资源造成的安全隐患的问题
缺点
需要耗费大量的CPU资源
看一个售票问题
import "ViewController.h"
@interface ViewController ()
/** 售票员1 */
@property (nonatomic, strong) NSThread *thread1;
/** 售票员2 */
@property (nonatomic, strong) NSThread *thread2;
/** 售票员3 */
@property (nonatomic, strong) NSThread *thread3;
/** 票数 */
@property (nonatomic, assign) NSInteger ticketsCount;
@end
@implementation ViewController
-
(void)viewDidLoad {
[super viewDidLoad];self.ticketsCount = 100;
self.thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
self.thread1.name = @"售票员1";self.thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
self.thread2.name = @"售票员2";self.thread3 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
self.thread3.name = @"售票员3";
} -
(void)saleTicket{
while (1) {
// 会记录锁的状态 @synchronized(self) { // 先取出总数 NSInteger count = self.ticketsCount; if (count > 0) { self.ticketsCount = count - 1; NSLog(@"%@卖了一张票,还剩下%zd张", [NSThread currentThread].name , self.ticketsCount); } else { NSLog(@"票已经卖完"); break; } }
}
}
-
(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self.thread1 start];
[self.thread2 start];
[self.thread3 start];
}
@end