进程
- 一个进程有一个或多个线程组成。进程只负责资源的调度和分配,线程才是程序正在的执行单元,负责代码的执行。
- 单线程 只有一个线程的程序,称作为单线程程序。
- 多线程 iOS允许用户自己开辟新的线程,相当于主线程来讲。这些线程,称为子线程;子线程和主线程都是独立的运行单元,各自的执行互不影响,因此能够并发执行。
- iOS中关于UI的添加和刷新必须在主线程中操作
创建子线程
//创建子线程
self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(subThread:) object:@"子线程启动"];
//启动子线程
[self.thread start];
GDC的学习
#pragma mark --- GCD的学习
//穿行队列:所有的任务在队里中顺序执行,相当于在operationQueue中将最大并大数设置为1的效果
//并行队列:所有的任务都是在队列中并发执行。
-(void)serialQueue{
//创建穿行队列
//第一个参数:当前队列的标记
//第二个参数:当前队列的类型设置 DISPATCH_QUEUE_SERIAL宏定义的值为NULL
// dispatch_queue_t sQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
//创建并行队列
dispatch_queue_t sQueue = dispatch_queue_create("conCurrent", DISPATCH_QUEUE_CONCURRENT);
//创建任务添加到队列中
//第一个参数:当前任务所要添加进的队列
//第二个参数:block,要执行的任务在block中执行
dispatch_async(sQueue, ^{
NSLog(@"1----%@",[NSThread currentThread]);
});
dispatch_async(sQueue, ^{
NSLog(@"2----%@",[NSThread currentThread]);
});
dispatch_async(sQueue, ^{
NSLog(@"3----%@",[NSThread currentThread]);
});
dispatch_async(sQueue, ^{
NSLog(@"4----%@",[NSThread currentThread]);
});
dispatch_async(sQueue, ^{
NSLog(@"5----%@",[NSThread currentThread]);
});
dispatch_async(sQueue, ^{
NSLog(@"6----%@",[NSThread currentThread]);
});
}
//全局队列 系统提供的一个并行队列,该全局队列,可以设置队列优先级
-(void)globalQueue{
//第一个参数:优先级设置
//第二个参数:预留参数,将来可能用到。目前直接赋值为0即可
dispatch_queue_t gQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(gQueue, ^{
NSLog(@"要执行的耗时操作----%@",[NSThread currentThread]);
//回主线程处理UI
//先得到一个主队列,将任务加入到主队列,在主队列执行的任务肯定在主线程中。
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
NSLog(@"我回到主线程了----%@",[NSThread currentThread]);
});
});
//简便写法。工作中经常用到的写法
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//处理耗时操作
//处理完数据回主线程
dispatch_async(dispatch_get_main_queue(), ^{
//回到主线程处理UI操作
});
});
}
//延迟执行
-(void)delayAction{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"延迟执行----%@",[NSThread currentThread]);
});
}
//某段代码执行一次
-(void)onceToken{
for (int i = 0; i < 10; i++) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
NSLog(@"某段代码执行一次");
});
}
}
//单列中GCD的应用
+(OperationQueueViewController*)sharedOperationQueueViewController{
static OperationQueueViewController* vc = nil;
//加线程锁也可以将该对象全局唯一,不会重复出现;但是效率比较低。由于效率低,所有我们一般不使用这种方式
// @synchronized(self) {
// if (vc == vc) {
// vc = [[OperationQueueViewController alloc] init];
// }
// }
//官方推荐的单例的写法
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//该block中代码只会被执行一次
vc = [[OperationQueueViewController alloc] init];
});
return vc;
}
任务队列
//任务队列:任务队列可以管理一组任务,它会根据当前的情况为任务开辟合适数量的子线程来完成任务,在队列中的任务,不需要手动启动。
//任务队列一般分为两种:主队列和其它队列。主队列:在主队列中的任务一定是在主线程中执行;其它队列:其它队列中的任务,一定是在子线程中执行。
//主队列
-(void)studyMainQueue{
//创建主队列对象
NSOperationQueue* mainQueue = [NSOperationQueue mainQueue];
NSBlockOperation* blockOperation_1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1----%@",[NSThread currentThread]);
}];
NSBlockOperation* blockOperation_2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"2----%@",[NSThread currentThread]);
}];
NSBlockOperation* blockOperation_3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"3----%@",[NSThread currentThread]);
}];
NSBlockOperation* blockOperation_4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"4----%@",[NSThread currentThread]);
}];
NSBlockOperation* blockOperation_5 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"5----%@",[NSThread currentThread]);
}];
//将任务加入到队列中,任务不用手动启动
// [mainQueue addOperation:blockOperation_1];
// [mainQueue addOperation:blockOperation_2];
// [mainQueue addOperation:blockOperation_3];
// [mainQueue addOperation:blockOperation_4];
// [mainQueue addOperation:blockOperation_5];
//主队列等待当前所在线程操作执行完毕之后,在执行队列中的任务
//主线程在等主队列中的任务执行完了,在接着做其它操作
//线程阻塞
NSLog(@"bbbb");
//YES:有可能会造成线程的阻塞
//NO:主线程无需等待任务执行完成,不会造成线程阻塞
[mainQueue addOperations:@[blockOperation_1,blockOperation_2,blockOperation_3,blockOperation_4,blockOperation_5] waitUntilFinished:NO];
NSLog(@"aaa");
}
//其它队列:一定在子线程中执行,任务是并发执行,没有先后顺序之分
-(void)studyOttheQueue{
//队列对象
NSOperationQueue* ohterQueue = [[NSOperationQueue alloc] init];
//创建任务添加到队列中
NSBlockOperation* blockOperation_1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1----%@",[NSThread currentThread]);
}];
NSBlockOperation* blockOperation_2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"2----%@",[NSThread currentThread]);
}];
NSBlockOperation* blockOperation_3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"3----%@",[NSThread currentThread]);
}];
NSBlockOperation* blockOperation_4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"4----%@",[NSThread currentThread]);
}];
NSBlockOperation* blockOperation_5 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"5----%@",[NSThread currentThread]);
}];
//如果某些任务是有先后顺序的,我们可以为任务添加依赖关系
//两个任务不能互相为依赖,否则,两个任务都不会执行
// [blockOperation_2 addDependency:blockOperation_1];
// [blockOperation_3 addDependency:blockOperation_2];
// [blockOperation_4 addDependency:blockOperation_3];
// [blockOperation_5 addDependency:blockOperation_4];
//如果想要所有的任务添加顺序执行,设置最大并大数
[ohterQueue setMaxConcurrentOperationCount:1];
//将任务加入到队列中,任务不用手动启动
[ohterQueue addOperation:blockOperation_1];
[ohterQueue addOperation:blockOperation_2];
[ohterQueue addOperation:blockOperation_3];
[ohterQueue addOperation:blockOperation_4];
[ohterQueue addOperation:blockOperation_5];
}
NSInvocationOperation任务对象
//NSInvocationOperation 任务对象,本身和线程无关,通过target—action的方法执行一个任务,需要调用start方法启动任务。
-(void)invocationOperation{
//初始化任务对象
NSInvocationOperation* operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationAction:) object:@"invocation"];
//启动任务
[operation start];
}
-(void)invocationAction:(NSString*)sender{
NSLog(@"sender----%@",sender);
NSLog(@"当前线程为:%@,是否是主线程:%d",[NSThread currentThread],[NSThread isMainThread]);
}
//NSBlockOPeration.和invocationOperation基本一致,只是通过block来实现操作
-(void)blockOperation{
NSBlockOperation* bOperation = [NSBlockOperation blockOperationWithBlock:^{
// NSLog(@"");
NSLog(@"blockOperation---%@",[NSThread currentThread]);
}];
//启动任务
[bOperation start];
}