程序:就是代码⽣成的可执⾏的应⽤。
进程:跑起来的程序。
线程:程序中独⽴运⾏的代码段。(block就是)。
⼀个进程是由多个线程(⼀个以上)组成的。进程申请资源和分配资源给线程⽤,线程⽤到资源。
每个进程都包含⾄少⼀个线程,即主线程。主线程在程序跑动的时候被创建,⽤于执⾏main函数⾥的东西。
主线程负责的是,所有代码的执⾏,包括UI更新,⽹络请求,本地存储等等。
主线程的代码都是顺序执⾏,不能并⾏执⾏。
⽤户可以开辟许多新的线程,这些线程都是主线程的⼦线程。
注意的是,主线程和⼦线程都是相互独⽴执⾏代码的,互不影响,并发执⾏。
注意:UI更新,必须放在主线程中去更新。因为开辟的⼦线程,是不受控制的,什么时候执⾏完毕我们⽆法控制。再⼦线程更新UI出现的bug⽆法预料。
NSThread是相对于后⾯两个NSOperationQueue、GCD来说,是⼀个轻量级的多线程。
//
// ViewController.m
// 多线程
//
// Created by cqy on 16/2/16.
// Copyright © 2016年 程清杨. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
{
NSThread *_thread;
int i ;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSThread *newThead = [NSThread currentThread];//获取当前线程
NSThread *mainThead = [NSThread mainThread];//获取主线程
[newThead setName:@"线程名"];
if ([newThead isMainThread]) {
NSLog(@"currentThread = %@",mainThead);
}
//第一种创建NSThread(第⼀种创建⽅式:需要⼿动启动[thread start];也要⼿动结束[thread cancel];⼦线程。)
//第⼀个参数:随来执⾏
// 第⼆个参数:去执⾏什么⽅法?这个⽅法⾥⼀般是⼦线程要完成的⼀些事:(⺴络请求,或者其他)。
// 第三个参数:去执⾏的那个⽅法,顺便带⼀个参数过去。
// NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(threadAction:) object:nil];
//手动开启线程
//[thread start];
//结束线程
//[thread cancel];
// //第⼆种创建⽅式:不需要⼿动去开启⼦线程。参数意义与第⼀种⼀样。
// [NSThread detachNewThreadSelector:@selector(threadAction:) toTarget:self withObject:@"qwe"];
//隐式创建线程
//[self performSelectorInBackground:@selector(threadAction:) withObject:self];
// 在主线程上执行
[self performSelectorOnMainThread:@selector(Open) withObject:self waitUntilDone:YES];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)Open{
NSLog(@"open...");
//新创建一个子线程
[NSThread detachNewThreadSelector:@selector(threadAction:) toTarget:self withObject:@"qwe"];
}
-(void)threadAction:(NSThread *)sender{
NSLog(@"threadAction...");
NSTimer *timer=[NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(timeSchedule) userInfo:nil repeats:YES];
NSRunLoop *runLoop=[NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
}
-(void)timeSchedule{
NSLog(@"timeSchedule...");
NSLog(@"now is %d",i++);
//在指定线程上执行操作
_thread = [[NSThread alloc]initWithTarget:self selector:@selector(WillClose) object:nil];
//暂停当前线程几秒
[NSThread sleepForTimeInterval:3];
[_thread start];
}
-(void)WillClose{
NSLog(@"will close...");
[self performSelector:@selector(Close) onThread:_thread withObject:nil waitUntilDone:YES];
}
-(void)Close{
NSLog(@"close............");
//停止当前线程
[NSThread exit];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
注意:
再多线程⽅法中,需要添加⾃动释放池。
应⽤程序再启动时,系统⾃动为主线程创建了⾃动释放池。我们⼿动添加的⼦
线程,需要添加⾃动释放池。
*/
// ViewController.m
// 多线程
//
// Created by cqy on 16/2/16.
// Copyright © 2016年 程清杨. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
{
NSThread *_thread;
int i ;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSThread *newThead = [NSThread currentThread];//获取当前线程
NSThread *mainThead = [NSThread mainThread];//获取主线程
[newThead setName:@"线程名"];
if ([newThead isMainThread]) {
NSLog(@"currentThread = %@",mainThead);
}
//第一种创建NSThread(第⼀种创建⽅式:需要⼿动启动[thread start];也要⼿动结束[thread cancel];⼦线程。)
//第⼀个参数:随来执⾏
// 第⼆个参数:去执⾏什么⽅法?这个⽅法⾥⼀般是⼦线程要完成的⼀些事:(⺴络请求,或者其他)。
// 第三个参数:去执⾏的那个⽅法,顺便带⼀个参数过去。
// NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(threadAction:) object:nil];
//手动开启线程
//[thread start];
//结束线程
//[thread cancel];
// //第⼆种创建⽅式:不需要⼿动去开启⼦线程。参数意义与第⼀种⼀样。
// [NSThread detachNewThreadSelector:@selector(threadAction:) toTarget:self withObject:@"qwe"];
//隐式创建线程
//[self performSelectorInBackground:@selector(threadAction:) withObject:self];
// 在主线程上执行
[self performSelectorOnMainThread:@selector(Open) withObject:self waitUntilDone:YES];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)Open{
NSLog(@"open...");
//新创建一个子线程
[NSThread detachNewThreadSelector:@selector(threadAction:) toTarget:self withObject:@"qwe"];
}
-(void)threadAction:(NSThread *)sender{
NSLog(@"threadAction...");
NSTimer *timer=[NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(timeSchedule) userInfo:nil repeats:YES];
NSRunLoop *runLoop=[NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
}
-(void)timeSchedule{
NSLog(@"timeSchedule...");
NSLog(@"now is %d",i++);
//在指定线程上执行操作
_thread = [[NSThread alloc]initWithTarget:self selector:@selector(WillClose) object:nil];
//暂停当前线程几秒
[NSThread sleepForTimeInterval:3];
[_thread start];
}
-(void)WillClose{
NSLog(@"will close...");
[self performSelector:@selector(Close) onThread:_thread withObject:nil waitUntilDone:YES];
}
-(void)Close{
NSLog(@"close............");
//停止当前线程
[NSThread exit];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
注意:
再多线程⽅法中,需要添加⾃动释放池。
应⽤程序再启动时,系统⾃动为主线程创建了⾃动释放池。我们⼿动添加的⼦
线程,需要添加⾃动释放池。
*/
@end
NSOperation
NSOperation
再mvc中属于M层,⽤来封装单个任务的相关代码的⼀个抽象类。这个抽象类不能直接使⽤,⽽是⽤它的⼦类来执⾏实际任务。
NSOperation只是⼀个操作,本⾝并没有主线程、⼦线程之分,可以使⽤再任意线程中。通常与NSOperationQueue⼀起使⽤。
//
// ViewController.m
// 多线程02-NSOperation
//
// Created by cqy on 16/2/16.
// Copyright © 2016年 程清杨. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSInvocationOperation *inOp = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationAction:) object:nil];
[inOp start];
//封装了要执⾏的代码块。要执⾏的代码都放在block⾥执⾏了。
NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"block操作0:%@",[NSThread currentThread]);
}];
//在NSBlockOperation对象中添加一个操作,如果NSBlockOperation对象包含了多个操作,有一个是在主线程中执行,其他均在子线程中
[blockOp addExecutionBlock:^{
NSLog(@"block操作1:%@",[NSThread currentThread]);
}];
[blockOp addExecutionBlock:^{
NSLog(@"block操作2:%@",[NSThread currentThread]);
}];
[blockOp start];
//注意:添加操作之前要放在start之前
//创建队列:将操作放入队列中(主队列除外),默认在子线程中执行,且不需要手动start
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSInvocationOperation *Operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run2) object:nil];
[queue addOperation:Operation];
[queue addOperationWithBlock:^{
NSLog(@"block操作队列3:%@",[NSThread currentThread]);
}];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)run2{
NSLog(@"队列执行操作4:%@",[NSThread currentThread]);
}
-(void)operationAction:(NSInvocationOperation *)sender{
NSLog(@"operationAction....");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// ViewController.m
// 多线程02-NSOperation
//
// Created by cqy on 16/2/16.
// Copyright © 2016年 程清杨. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSInvocationOperation *inOp = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationAction:) object:nil];
[inOp start];
//封装了要执⾏的代码块。要执⾏的代码都放在block⾥执⾏了。
NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"block操作0:%@",[NSThread currentThread]);
}];
//在NSBlockOperation对象中添加一个操作,如果NSBlockOperation对象包含了多个操作,有一个是在主线程中执行,其他均在子线程中
[blockOp addExecutionBlock:^{
NSLog(@"block操作1:%@",[NSThread currentThread]);
}];
[blockOp addExecutionBlock:^{
NSLog(@"block操作2:%@",[NSThread currentThread]);
}];
[blockOp start];
//注意:添加操作之前要放在start之前
//创建队列:将操作放入队列中(主队列除外),默认在子线程中执行,且不需要手动start
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSInvocationOperation *Operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run2) object:nil];
[queue addOperation:Operation];
[queue addOperationWithBlock:^{
NSLog(@"block操作队列3:%@",[NSThread currentThread]);
}];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)run2{
NSLog(@"队列执行操作4:%@",[NSThread currentThread]);
}
-(void)operationAction:(NSInvocationOperation *)sender{
NSLog(@"operationAction....");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
GCD
GCD是苹果公司封装好的⼀个系统,⽤来应对多核处理系统。gcd⼤部分代码都是函数的多线程,性能⾼,功能强⼤。
GCD以队列的⽅式进⾏⼯作,先进先出(o),GCD根据分发队列的的类型,创建适量线程,完成⼯作。
cgd分为三种队列:
主队列,全局队列,⾃定义队列。
1、串⾏队列:前⼀个任务完成,才能执⾏下⼀个任务(包括主队列和⾃定义队列)
2、并⾏队列:各个任务独⽴执⾏,互不⼲扰,也是先进先出(包括了全局队列和⾃定义队列)。
//
// ViewController.m
// 多线程03-GCD
//
// Created by cqy on 16/2/16.
// Copyright © 2016年 程清杨. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self oneMain];
[self twoMain];
[self threeMain];
[self fourMain];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)oneMain{
// 主队列(串)
//dispatch_queue_t是⼀个类型,mainQueue是类型的实例名。
dispatch_queue_t mainQueue = dispatch_get_main_queue();
//dispatch_get_main_queue(),获取主队列
// 添加任务(三种队列都⽤这个⽅法添加)
dispatch_async(mainQueue, ^{
//dispatch_async(mainQueue,^(block)),这个⽅法是吧任务添加到mainQueue主队列中。block块⾥是要执⾏的任务。
NSLog(@"第1个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第2个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第3个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第4个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第5个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第6个任务,当前线程:%@",[NSThread currentThread]);
});
//解释:1、dispatch_queue_create 是创建⾃定义队列的⽅式。第⼀个参数是队列标⽰符,第⼆个参数是告诉系统,这个队列是串⾏的。2、dispatch_async,添加任务到myQueue1这个⾃定义队列中。block块中是执⾏的任务。
}
-(void)twoMain{
// ⾃定义队列(串)
// 第⼆个参数,告诉是串⾏的。
dispatch_queue_t myQueue = dispatch_queue_create("myQ1", DISPATCH_QUEUE_SERIAL);
dispatch_async(myQueue, ^{
NSLog(@"第01个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"第02个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"第03个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"第04个任务,当前线程:%@",[NSThread currentThread]);
});
}
-(void)threeMain{
// 全局(并⾏)
dispatch_queue_t globelQ =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);
dispatch_async(globelQ, ^{
NSLog(@"第-1个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(globelQ, ^{
NSLog(@"第-2个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(globelQ, ^{
NSLog(@"第-3个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(globelQ, ^{
NSLog(@"第-5个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(globelQ, ^{
NSLog(@"第-6个任务,当前线程为:%@",[NSThread currentThread]);
});
// 解释dispatch_get_global_queue创建⼀个全局队列。DISPATCH_QUEUE_PRIORITY_DEFAULT:队列的优先级,default是系统默认。
}
-(void)fourMain{
// ⾃定义(并⾏)
dispatch_queue_t myQueue2 = dispatch_queue_create("Q2", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myQueue2, ^{
NSLog(@"第1-个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(myQueue2, ^{
NSLog(@"第2-个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(myQueue2, ^{
NSLog(@"第3-个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(myQueue2, ^{
NSLog(@"第4-个任务,当前线程为:%@",[NSThread currentThread]);
});
//解释:dispatch_queue_create 创建⾃定义队列。第⼀个参数是队列标⽰符,第⼆个参数:DISPATCH_QUEUE_CONCURRENT是告诉系统,创建的是并⾏的队列。
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// ViewController.m
// 多线程03-GCD
//
// Created by cqy on 16/2/16.
// Copyright © 2016年 程清杨. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self oneMain];
[self twoMain];
[self threeMain];
[self fourMain];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)oneMain{
// 主队列(串)
//dispatch_queue_t是⼀个类型,mainQueue是类型的实例名。
dispatch_queue_t mainQueue = dispatch_get_main_queue();
//dispatch_get_main_queue(),获取主队列
// 添加任务(三种队列都⽤这个⽅法添加)
dispatch_async(mainQueue, ^{
//dispatch_async(mainQueue,^(block)),这个⽅法是吧任务添加到mainQueue主队列中。block块⾥是要执⾏的任务。
NSLog(@"第1个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第2个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第3个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第4个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第5个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"第6个任务,当前线程:%@",[NSThread currentThread]);
});
//解释:1、dispatch_queue_create 是创建⾃定义队列的⽅式。第⼀个参数是队列标⽰符,第⼆个参数是告诉系统,这个队列是串⾏的。2、dispatch_async,添加任务到myQueue1这个⾃定义队列中。block块中是执⾏的任务。
}
-(void)twoMain{
// ⾃定义队列(串)
// 第⼆个参数,告诉是串⾏的。
dispatch_queue_t myQueue = dispatch_queue_create("myQ1", DISPATCH_QUEUE_SERIAL);
dispatch_async(myQueue, ^{
NSLog(@"第01个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"第02个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"第03个任务,当前线程:%@",[NSThread currentThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"第04个任务,当前线程:%@",[NSThread currentThread]);
});
}
-(void)threeMain{
// 全局(并⾏)
dispatch_queue_t globelQ =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);
dispatch_async(globelQ, ^{
NSLog(@"第-1个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(globelQ, ^{
NSLog(@"第-2个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(globelQ, ^{
NSLog(@"第-3个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(globelQ, ^{
NSLog(@"第-5个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(globelQ, ^{
NSLog(@"第-6个任务,当前线程为:%@",[NSThread currentThread]);
});
// 解释dispatch_get_global_queue创建⼀个全局队列。DISPATCH_QUEUE_PRIORITY_DEFAULT:队列的优先级,default是系统默认。
}
-(void)fourMain{
// ⾃定义(并⾏)
dispatch_queue_t myQueue2 = dispatch_queue_create("Q2", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myQueue2, ^{
NSLog(@"第1-个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(myQueue2, ^{
NSLog(@"第2-个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(myQueue2, ^{
NSLog(@"第3-个任务,当前线程为:%@",[NSThread currentThread]);
});
dispatch_async(myQueue2, ^{
NSLog(@"第4-个任务,当前线程为:%@",[NSThread currentThread]);
});
//解释:dispatch_queue_create 创建⾃定义队列。第⼀个参数是队列标⽰符,第⼆个参数:DISPATCH_QUEUE_CONCURRENT是告诉系统,创建的是并⾏的队列。
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end