NSTread
NSLog(@"当前是否处于主线程:%d",[NSThread isMainThread]);
//获取主线程
[NSThread mainThread];
//创建线程方法
[NSThread detachNewThreadSelector:@selector(thread1) toTarget:self withObject:nil];
//开启线程第二种方法
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(thread2) object:nil];
//设置线程名称
thread2.name = @"工作线程2";
//线程优先级(不建议使用,如果过多设置优先级,可能会导致某些线程不执行)
// thread2.threadPriority;
//开始执行该线程
[thread2 start];
//线程可能不按照顺序创建(两个网络请求,无法确定两个谁先请求完毕)
[NSThread currentThread];
//创建任务(可以认为是轻量级的线程,默认是添加到主队列中,系统会在空闲期间自动执行任务)
NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operation1) object:nil];
//执行任务
// [operation1 start];
//设置任务完成的回调
[operation1 setCompletionBlock:^{
NSLog(@"任务1完成!");
}];
//创建任务2
NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operation2) object:nil];
// [operation2 start];
//添加对任务1的依赖(任务1执行完毕才去执行任务2)
[operation2 addDependency:operation1];
// operation1.concurrent
//创建队列(默认会并行执行内部任务)
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//队列中最大并发数量,默认值为-1(代表队列所有任务同时执行,设置为1代表串行)
queue.maxConcurrentOperationCount = 1;
//往队列中添加任务(队列会自动执行内部的任务)
[queue addOperation:operation1];
[queue addOperation:operation2];
// [queue cancelAllOperations];
//创建block任务
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i<10; i++) {
NSLog(@"任务三:%d",i);
sleep(1);
}
}];
[operation3 start];
//创建自定义任务
CustomOperation *cusOp = [[CustomOperation alloc]init];
//弱引用
__weak typeof(cusOp)wOp = cusOp;
//拷贝
__block typeof(cusOp)bOp = cusOp;
[cusOp setCompletionBlock:^{
//回到主线程修改UI
[self performSelectorOnMainThread:@selector(addImgView:) withObject:wOp.data waitUntilDone:NO];
}];
[cusOp start];
GCD是Grand central Dispatch的缩写,是一系列BSD层面的接口。
//Grand Central Dispatch(多线程优化技术)或称GCD,是一套底层API,提供了新的模式编写并发执行的程序。功能类似于NSOperationQueue,允许将一个程序切分为多个单一任务,然后提交到工作队列并并发地或者串行地执行。但GCD比后者更底层更高效。
//GCD采用队列的方式管理线程,不仅可以管理多线程,并发的任务,设置主线程,也通过任务队列的方式进行管理。
//所以说GCD的队列是任务队列,而不是线程队列。
一、Dispatch Queues
1.The main queue(主队列,串行执行):
提交到main queue的任务将在主线程执行。main queue可以调用dispatch_get_main_queue()来获得。因为main queue是与主线程相关的,所以这是一个串行队列。
2.Global queues(全局队列,并行执行):
全局队列是并发队列,并由整个进程共享。进程中存在三个全局队列,可以调用dispatch_get_global_queue函数,传入优先级来访问队列。
3.用户队列(用户队列,串行执行):
用户队列(GCD中对这种队列没有特定的名词来描述,姑且如此称之)可以使用dispatch_queue_create函数创建队列。这些队列是串行执行的。
//创建一个GCD任务
gcdQueue = dispatch_queue_create("heima GCD", NULL);
//往异步队列中添加异步任务
dispatch_async(gcdQueue, ^(void){
…
});
【注】原则上,官方只允许UI主线程修改UI,虽然部分第三方库,并不是这样。不允许工作线程修改如progress进度读条等UI控件。
//比如下载数据,修改进度条的工作应当由主线程完成。
//
// ViewController.m
// GCD
//
//
#import "ViewController.h"
@interface ViewController ()
{
dispatch_queue_t _mainQueue; // 主线程
dispatch_queue_t _globalQueue; // 全局线程
dispatch_queue_t _myQueue; // 自定义线程队列
UIProgressView *_progressView;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 获取到主线程队列
_mainQueue = dispatch_get_main_queue();
// [self mainQueue];
// 获取到全局线程
_globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// [self globalQueue];
// 自定义线程队列
// dispatch_queue_create(线程名,线程类型)
// 线程类型 DISPATCH_QUEUE_SERIAL 串行
// DISPATCH_QUEUE_CONCURRENT 并行
_myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
[self myQueue];
// 主线程刷新UI
// 进度条视图
_progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(10, 100, 300, 10)];
[self.view addSubview:_progressView];
/** GCD
NSThread
NSOperationQueue
封装程度:由低到高,封装程度越低,使用越简单
*/
dispatch_async(_globalQueue, ^{
for (int i = 0; i < 10; i++) {
// self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>
dispatch_async(_mainQueue, ^{
[_progressView setProgress:0.1 * i animated:YES];
});
[NSThread sleepForTimeInterval:1.0];
}
});
}
- (void)mainQueue {
// 在主线程队列异步执行: 串行执行
dispatch_async(_mainQueue, ^{
NSLog(@"1主线程队列:%i", [NSThread isMainThread]);
});
dispatch_async(_mainQueue, ^{
NSLog(@"2主线程队列:%i", [NSThread isMainThread]);
});
dispatch_async(_mainQueue, ^{
NSLog(@"3主线程队列:%i", [NSThread isMainThread]);
});
dispatch_async(_mainQueue, ^{
NSLog(@"4主线程队列:%i", [NSThread isMainThread]);
});
}
- (void)globalQueue {
// 全局线程队列,同步执行:主线程
dispatch_sync(_globalQueue, ^{
NSLog(@"全局线程队列同步:%i", [NSThread isMainThread]);
});
// 全局线程队列,异步执行:子线程
dispatch_async(_globalQueue, ^{
NSLog(@"全局线程队列异步:%i", [NSThread isMainThread]);
});
// 同步执行:串行执行,顺序执行
dispatch_sync(_globalQueue, ^{
NSLog(@"1");
});
dispatch_sync(_globalQueue, ^{
NSLog(@"2");
});
dispatch_sync(_globalQueue, ^{
NSLog(@"3");
});
dispatch_sync(_globalQueue, ^{
NSLog(@"4");
});
// 异步执行: 并行执行,不按顺序执行
dispatch_async(_globalQueue, ^{
NSLog(@"5");
});
dispatch_async(_globalQueue, ^{
NSLog(@"6");
});
dispatch_async(_globalQueue, ^{
NSLog(@"7");
});
dispatch_async(_globalQueue, ^{
NSLog(@"8");
});
}
#pragma mark 自定义线程队列
- (void)myQueue {
// 自定义线程队列,同步执行:主线程
dispatch_sync(_myQueue, ^{
NSLog(@"自定义线程队列:%i", [NSThread isMainThread]);
});
// 自定义线程队列,异步执行:子线程
dispatch_async(_myQueue, ^{
NSLog(@"自定义线程队列:%i", [NSThread isMainThread]);
});
/* 自定义线程队列(串行)
同步:串行 异步:串行
自定义线程队列(并行)
同步:串行 异步:并行
*/
dispatch_sync(_myQueue, ^{
NSLog(@"1");
});
dispatch_sync(_myQueue, ^{
NSLog(@"2");
});
dispatch_sync(_myQueue, ^{
NSLog(@"3");
});
dispatch_sync(_myQueue, ^{
NSLog(@"4");
});
dispatch_async(_myQueue, ^{
NSLog(@"5");
});
dispatch_async(_myQueue, ^{
NSLog(@"6");
});
dispatch_async(_myQueue, ^{
NSLog(@"7");
});
dispatch_async(_myQueue, ^{
NSLog(@"8");
});
}
/** 单例模式
一般用于在项目中只需要一个实例的情况.比如,User,Tool,NetWork, DBManager
*/
+ (instancetype)shareViewController {
static ViewController *vc = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
vc = [[ViewController alloc] init];
});
return vc;
}
@end