1. pthread
1). 执行不带参数的方法
import <pthread/pthread.h>
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 创建子线程,线程编号
pthread_t pthread;
// 第一个参数 线程编号的地址
// 第二个参数 线程的属性
// 第三个参数 线程的要执行的函数
// 第四个参数 要执行的函数的参数
// 返回值 int 0是成功 非0是失败
int result = pthread_create(&pthread, NULL, demo, NULL);
NSLog(@"touchesBegan %@", [NSThread currentThread]);
if (result) {
NSLog(@"失败");
} else {
NSLog(@"成功");
}
}
// 函数必须是C语言的
void *demo(void *param) {
NSLog(@"hello %@", [NSThread currentThread]);
return NULL;
}
2). 执行带参数的方法
#import <pthread/pthread.h>
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 创建子线程, 线程编号
pthread_t pthread;
char *nameC = "mazaiting";
int result = pthread_create(&pthread, NULL, demo, (void *)nameC);
if (result) {
NSLog(@"失败");
} else {
NSLog(@"成功");
}
NSString *nameNS = @"zaitingma";
// 传参时要将OC中的对象传递给C语言的函数,要使用桥接, __bridge
int result1 = pthread_create(&pthread, NULL, demo1, (__bridge void *)nameNS);
if (result1) {
NSLog(@"失败");
} else {
NSLog(@"成功");
}
}
// C函数, 传递OC对象
void *demo1(void *param) {
NSString *string = (__bridge NSString *)param;
NSLog(@"%@", string);
return NULL;
}
// C函数, 传递C字符串
void *demo(void *param) {
char *string = param;
NSLog(@"%s", string);
return NULL;
}
2. NSThread
1). 创建线程
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self createThread];
}
- (void)createThread {
// 方式一
// 创建线程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
// 开启线程
[thread start];
// 方式二
[NSThread detachNewThreadSelector:@selector(demo) toTarget:self withObject:nil];
// 方式三
[self performSelectorInBackground:@selector(demo) withObject:nil];
// 方式4 带参数
NSThread *threadParam = [[NSThread alloc] initWithTarget:self selector:@selector(demo1:) object:@"mazaiting"];
[threadParam start];
}
- (void)demo1:(NSString *)name {
NSLog(@"%@", name);
}
- (void)demo {
// 打印当前线程
NSLog(@"hello %@", [NSThread currentThread]);
}
2). 线程状态
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 新建状态
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
// 线程名
thread.name=@"t1";
// 线程的优先级
thread.threadPriority=1.0;
// 就绪状态
[thread start];
}
- (void)demo {
for (int i = 0; i < 20; i++) {
NSLog(@"%d", i);
if (i == 5) {
// 阻塞状态 -- 睡眠3秒
[NSThread sleepForTimeInterval:3];
}
if (i == 10) {
// 线程退出 -- 死亡状态
[NSThread exit];
}
// 判断是否是主线程
if([NSThread isMainThread]){
continue;
}
}
}
3). 线程互斥锁
- (void)demo1 {
// 互斥锁
@synchronized(self) {
NSLog(@"%@",self);
}
}
4). 自旋锁
@property (nonatomic, copy) NSString *name;
// 为属性生成对应的成员变量
@synthesize name = _name;
5). 三种Block
//2 block 为什么要用copy
//第一种 block 全局block __NSGlobalBlock__
// void (^demo)() = ^{
// NSLog(@"aaa");
// };
// NSLog(@"%@",demo);
//第二种block 栈Block __NSStackBlock__
// int number = 5;
// void (^demo)() = ^{
// NSLog(@"aaa %d",number);
// };
// NSLog(@"%@",demo);
//第三种block 堆block __NSMallocBlock__
// int number = 5;
// void (^demo)() = ^{
// NSLog(@"aaa %d",number);
// };
// NSLog(@"%@",[demo copy]);
6). 子线程消息循环
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 开启一个子线程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
[thread start];
// 往子线程的消息循环中添加输入源
[self performSelector:@selector(demo1) onThread:thread withObject:nil waitUntilDone:NO];
}
// 执行在子线程上的方法
- (void)demo {
NSLog(@"I am running!");
// 开启子线程的消息循环,如果开启,消息循环一直运行
// 当子线程循环中没有添加输入事件,消息循环会立即结束
// [[NSRunLoop currentRunLoop] run];
// 2秒钟后消息循环结束
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
NSLog(@"end");
}
// 执行在子线程的消息循环中
- (void)demo1 {
NSLog(@"I'm running on runloop!");
}
@end
3. GCD
1). 简单使用
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 1. 创建队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 2. 创建任务
dispatch_block_t task = ^ {
NSLog(@"hello %@",[NSThread currentThread]);
};
// 3. 异步执行
dispatch_async(queue, task);
// 简化用法
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"mazaiting %@", [NSThread currentThread]);
// 回到主线程
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"----%@", [NSThread mainThread]);
});
});
}
@end
2). 串行队列
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self sync];
[self async];
}
// 串行队列,同步执行 不开新线程,任务是顺序执行的
- (void)sync {
dispatch_queue_t queue = dispatch_queue_create("mazaiting", DISPATCH_QUEUE_SERIAL);
for (int i = 0; i < 10; i++) {
dispatch_sync(queue, ^{
NSLog(@"%d---%@", i, [NSThread currentThread]);
});
}
}
// 串行队列,异步执行 开新线程(1个),任务是有序执行的
- (void)async {
dispatch_queue_t queue = dispatch_queue_create("mazaiting", DISPATCH_QUEUE_SERIAL);
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
NSLog(@"%d---%@", i, [NSThread currentThread]);
});
}
}
@end
3). 并行队列
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self sync];
[self async];
}
// 并行队列,同步执行 --- 串行队列,同步执行,不开线程,顺序执行
- (void)sync {
dispatch_queue_t queue = dispatch_queue_create("mazaiting", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 10; i++) {
dispatch_sync(queue, ^{
NSLog(@"%d---%@", i, [NSThread currentThread]);
});
}
}
// 并行队列,异步执行 --- 开多个线程,无序执行
- (void)async {
dispatch_queue_t queue = dispatch_queue_create("mazaiting", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
NSLog(@"%d---%@", i, [NSThread currentThread]);
});
}
}
@end
4). 主队列
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// [self demo];
// [self demo1];
[self demo2];
}
// 1. 主队列,异步执行 --- 主线程,顺序执行
// 主队列特点:先执行完主线程上的代码,才会执行主队列中的任务
- (void)demo {
for (int i = 0; i < 10; i++) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"hello %d %@", i, [NSThread currentThread]);
});
}
}
// 2. 主队列,同步执行 --- 主线程上执行才会死锁
// 同步执行: 会等着第一个任务执行完成后才会继续往后执行
- (void)demo1 {
NSLog(@"开始");
for (int i = 0; i < 10; i++) {
// 死锁
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"hello %d %@", i, [NSThread currentThread]);
});
}
NSLog(@"结束");
}
// 3. 解决死锁
- (void)demo2 {
NSLog(@"开始");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
for (int i = 0; i < 10; i++) {
// 死锁
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"hello %d %@", i, [NSThread currentThread]);
});
}
});
NSLog(@"结束");
}
@end
5). 延迟执行和一次性执行
//1 延迟执行
// dispatch_time_t when, 延迟多长时间 精度到纳秒
// dispatch_queue_t queue, 队列
// dispatch_block_t block 任务
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//
// NSLog(@"task");
// });
//2 一次性执行
// for (int i = 0; i<20000; i++) {
// static dispatch_once_t onceToken;
// dispatch_once(&onceToken, ^{
// NSLog(@"hello %@",[NSThread currentThread]);
// });
// }
6). 调度组
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
//下载三首歌曲,当歌曲都下载完毕 通知用户
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self demo2];
}
//调度组内部的原理
- (void)demo2 {
//创建组
dispatch_group_t group = dispatch_group_create();
//创建队列
dispatch_queue_t queue = dispatch_queue_create("hm", DISPATCH_QUEUE_CONCURRENT);
//任务1
dispatch_group_enter(group);
dispatch_async(queue, ^{
NSLog(@"任务1");
dispatch_group_leave(group);
});
//任务2
dispatch_group_enter(group);
dispatch_async(queue, ^{
NSLog(@"任务2");
dispatch_group_leave(group);
});
//任务3
dispatch_group_enter(group);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2.0];
NSLog(@"任务3");
dispatch_group_leave(group);
});
//等待组中的任务都执行完毕,才会执行
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"over");
});
//等待组中的任务都执行完毕,才会继续执行后续的代码
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"hello ");
}
//演示调度组的基本使用
- (void)demo1 {
//创建组
dispatch_group_t group = dispatch_group_create();
//队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//下载第一首歌曲
dispatch_group_async(group, queue, ^{
NSLog(@"正在下载第一个歌曲");
});
//下载第二首歌曲
dispatch_group_async(group, queue, ^{
NSLog(@"正在下载第二个歌曲");
[NSThread sleepForTimeInterval:2.0];
});
//下载第三首歌曲
dispatch_group_async(group, queue, ^{
NSLog(@"正在下载第三个歌曲");
});
//当三个异步任务都执行完成,才执行
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"over %@",[NSThread currentThread]);
});
}
@end
4. NSOperation
1). 创建
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 1. 调用start执行, 不会开启新线程,start方法更新操作的状态,调用main方法
// 创建
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demo) object:nil];
NSLog(@"--%d", op.isFinished);
// 开始执行
[op start];
NSLog(@"--%d", op.isFinished);
// 2. 添加到队列
// 创建操作
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demo) object:nil];
// 添加到队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 将操作添加到队列
[queue addOperation:op1];
}
- (void)demo {
NSLog(@"hello %@", [NSThread currentThread]);
}
@end
2). BlockOperation
#import "ViewController.h"
@interface ViewController ()
//全局队列
@property (nonatomic, strong) NSOperationQueue *queue;
@end
@implementation ViewController
//懒加载
- (NSOperationQueue *)queue {
if (_queue == nil) {
_queue = [[NSOperationQueue alloc] init];
}
return _queue;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self demo5];
}
//演示start
- (void)demo1 {
//创建操作
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"hello %@",[NSThread currentThread]);
}];
//更新op的状态,执行main方法
[op start]; //不会开新线程
}
//把操作添加到队列
- (void)demo2 {
//创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//创建操作
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"hello %@",[NSThread currentThread]);
}];
//把操作添加到队列中
[queue addOperation:op];
}
- (void)demo3 {
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
NSLog(@"hello %@",[NSThread currentThread]);
}];
}
//全局队列
- (void)demo4 {
// //并发队列,异步执行
// for (int i = 0; i < 10; i++) {
// [self.queue addOperationWithBlock:^{
// NSLog(@"hello %d %@",i,[NSThread currentThread]);
// }];
// }
}
// 操作的 completionBlock
- (void)demo5 {
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:2];
NSLog(@"hello %@",[NSThread currentThread]);
}];
//操作完成之后执行
[op setCompletionBlock:^{
NSLog(@"end %@",[NSThread currentThread]);
}];
[self.queue addOperation:op];
}
@end
3). 线程间通信
#import "ViewController.h"
@interface ViewController ()
//全局队列
@property (nonatomic, strong) NSOperationQueue *queue;
@end
@implementation ViewController
//懒加载
- (NSOperationQueue *)queue {
if (_queue == nil) {
_queue = [[NSOperationQueue alloc] init];
}
return _queue;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.queue addOperationWithBlock:^{
//异步下载图片
NSLog(@"异步下载图片");
//获取当前队列
// [NSOperationQueue currentQueue]
//线程间通信,回到主线程更新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"更新UI");
}];
}];
}
@end
4). 操作的依赖
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) NSOperationQueue *queue;
@end
@implementation ViewController
- (NSOperationQueue *)queue {
if (_queue == nil) {
_queue = [NSOperationQueue new];
}
return _queue;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 下载 - 解压 - 升级完成
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载");
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:2.0];
NSLog(@"解压");
}];
//设置优先级最高
op2.qualityOfService = NSQualityOfServiceUserInteractive;
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"升级完成");
}];
//设置操作间的依赖
[op2 addDependency:op1];
[op3 addDependency:op2];
//错误,会发生循环依赖,什么都不执行
// [op1 addDependency:op3];
//操作添加到队列中
[self.queue addOperations:@[op1,op2] waitUntilFinished:NO];
//依赖关系可以夸队列执行
[[NSOperationQueue mainQueue] addOperation:op3];
}
@end
5). 自定义操作
- 步骤: 继承NSOperation类,并重写main方法
CustomOperation.h
#import <Foundation/Foundation.h>
@interface CustomOperation : NSOperation
@end
CustomOperation.m
#import "CustomOperation.h"
@implementation CustomOperation
- (void)main {
NSLog(@"mazaiting");
}
@end
ViewController.m
#import "ViewController.h"
#import "CustomOperation.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
CustomOperation *co = [[CustomOperation alloc] init];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:co];
}
@end