一.概念.
1.进程:正在活动(或者运行)的一个应用程序就是一个进程
2.主线程 : 每一个进程 都能至少有一条线程 叫 主线程'
3.线程:每一个线程都是相互独立的,可以执行任务 , 除了主线程以外的,都叫子线程.
4.子线程可以有多个,但是线程是耗费资源的. 在我们 ios开发中一般不超过5条,注:3条差不多了.
5.程序退出后 会清空线程的任务, 就是消灭应用程序对应的那条进程
6.主线程 操作什么样的任务?? 答:UI界面,按钮的点击,屏幕的滚动(一切用户看的见的 都要在主线程当中去操作). 而那些比较大的耗时的操作或者用户看不到的操作可以放到线程当中去做,比如:下载,解压缩,读取大型数据等 可以在子线程中去操作
7.多线程的原理:CPU在工作时 : 同一时间内,只执行一个任务,之所以可以造成多条线程一起执行任务的假象,是CPU在进行高速的切换(在线程之间进行调度)来达到多个任务一起执行的效果
8说说多线程的优点:1.可以大大提高执行任务的效率2.可以让用户有更好的体验
缺点:如果大量的开辟线程,会造成程序的卡顿(耗费过量的资源) 物极必反
9. (1)查询当前的线程:[NSThread currentThread] 如果输出结果中number = 1,则表示在主线程中,反之,则表示在子线程中
(2)线程休眠:[NSThread sleepForTimeInterval:5];
(3)立即结束当前线程 : [NSThread exit];
(4)判断当前线程 是否是主线程:[NSThread isMainThread];
10.开辟子线程的方法
[self performSelector:@selector(downLoad:) withObject:@"123"];
[self performSelectorInBackground:@selector(downLoad:) withObject:@"123"];
#pragma mark --- NSTread
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(downLoad:)object:@“123”];
[thread start];
[NSThread detachNewThreadSelector:@selector(downLoad:)toTarget:self withObject:@“123”];
#pragma mark — 常用的开启多线程的方法
优势:不用程序员 管理 线程的生命周期
1.NSOperation:封装了一下GCD的方法 提供OC语言来使用GCD
2.GCD:是苹果推荐的 可以最大化的发挥多核CPU 是C语言的函数
NSOperation 是一个抽象类 : 子类 : NSBlockOperation 和 NSInvocationOperation
概念:
1.线程队列:(任务中心 可以执行很多任务)
串行队列(主线程相当于一个串行队列 队列中的任务需要执行完毕一个后,再执行下一个)
并行队列:队列中的任务需要并行执行 . 同时开始,但未必同时结束
2.同步:没有开启子线程的能力
异步:具备开启子线程的能力
3.什么是任务?? 比如下载,打印 都是个任务
4.注意”使用GCD 或者 NSOperation 咱们要做的就是往合适的队列中添加任务,其他的根咱们无关,系统会根据队列的类型 来开启线程去完成任务
5.线程建的通信: 在子线程中 完成耗时的操作 , 完成后 需要回到主线程里进行UI的刷新 这里就需要线程的通信
6.主线程 和 子线程是独立的
7.具体的实现
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:2];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downLoad:) object:@"123"];
[queue addOperation:operation];
[queue addOperationWithBlock:^{
NSLog(@"任务2所在线程为---%@",[NSThread currentThread]);
}];
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务4所在线程为---%@",[NSThread currentThread]);
}];
[queue addOperation:blockOperation];
}
#pragma mark — 开启子线程 请求一张图片 请求完成后 回到主线程 显示图片(刷新UI)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self performSelectorInBackground:@selector(imageDownLoad:) withObject:kImageURL];
}
- (void)imageDownLoad:(NSString *)str
{
NSLog(@"我在子线程%@",[NSThread currentThread]);
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:str]];
UIImage *image = [UIImage imageWithData:data];
[self performSelector:@selector(ShowImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
}
- (void)ShowImage:(UIImage *)image
{
self.imageV.image = image;
NSLog(@"是否回到主线程?---%@",[NSThread currentThread]);
}
#pragma mark — 重点:GCD
概念:
1.队列: 并行队列:系统提供了一个全局的并行队列(整个应用都可以使用) 如果不想用 也可以自己创建出来
串行队列:需要自己创建一个出来
2.任务:同步:不具备开启线程的能力
异步:具有开启线程的能力
分为4种情况:
1.并行 --- 异步任务 (主要用的)
2.并行 --- 同步任务
3.串行 --- 异步任务
4.串行 --- 同步任务
#pragma mark ---- 1.并行 --- 异步任务
- (void)asyncGlobalQueue
{
dispatch_queue_t queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_async(queue, ^{
NSLog(@"任务1, 在线程 ---- %@",[NSThread currentThread]);
});
}
#pragma mark ---- 2.并行 --- 同步任务
- (void)syncGlobalQueue
{
dispatch_queue_t queue = dispatch_queue_create("com.lanou3g.www", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
NSLog(@"任务1, 在线程 ---- %@",[NSThread currentThread]);
});
dispatch_release(queue);
}
#pragma mark ---- 2.串行 --- 异步任务
- (void)asyncSerialQueue
{
dispatch_queue_t queue = dispatch_queue_create("com.lanou3g.www", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"任务1, 在线程 ---- %@",[NSThread currentThread]);
});
dispatch_release(queue);
}
#pragma mark ---- 4.串行 --- 同步任务
- (void)syncSerialQueue
{
dispatch_queue_t queue = dispatch_queue_create("com.lanou3g.www", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"任务1, 在线程 ---- %@",[NSThread currentThread]);
});
dispatch_release(queue);
}
- (void)viewDidLoad {
[super viewDidLoad];
{
#pragma mark --- GCD开启子线程加载图片 回到主线程刷新UI
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic2.ooopic.com/01/03/51/25b1OOOPIC19.jpg"]];
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
...
});
});
}
#pragma mark --- 实现模拟卖票
self.lock = [[NSLock alloc] init];
self.ticketCounts = 100;
[self tickets];
}
- (void)tickets
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
[self sellTicket];
});
dispatch_async(queue, ^{
[self sellTicket];
});
dispatch_async(queue, ^{
[self sellTicket];
});
}
- (void)sellTicket
{
while (1) {
@synchronized(self){
if (self.ticketCounts > 0) {
self.ticketCounts--;
NSLog(@"剩余的票数---%ld 谁丶买走了票---%@",self.ticketCounts,[NSThread currentThread]);
} else {
return;
}
}
}
}
#pragma mark ---
+(MyHandle *)shareHandle
{
static MyHandle *handle = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
handle = [[MyHandle alloc] init];
});
return handle;
}