前言:
//判断当前代码执行的时候是否是在主线程
BOOL isMainThread = [[NSThread currentThread] isMainThread];
NSLog(@"%d",isMainThread);
主线程阻塞会造成UI冻结,页面假死
例如:
NSInteger count = 0 ;
for (int i = 0; i <1000000000; i++) {
count++;
}
count++;
}
NSLog(@"%ld",count);
实现多线程的方法: 1. NSObject实现多线程
2. NSThread实例方法实现多线程
3.NSThread类方法实现多线程
4.NSOperationQueue实现多线程
5.GCD(Grand Center Dispatch)大中央调度 以队列的方式管理多线程
1.NSObject实现多线程:
NSObject提供的方法实现多线程,使用简单,但不能保证线程安全
[self performSelectorInBackground:@selector(NSObjectAction:) withObject:@“
"NSObject
实现多线程
”];
-(void)NSObjectAction:(id)object
{
BOOL isMainThread = [[NSThread currentThread] isMainThread];
NSLog(@"%d",isMainThread);
NSLog(@"%@",object);
NSInteger count = 0 ;
for (NSInteger i = 0; i <10000000000; i++) {
count++;
}
NSLog(@"%ld" ,count);
{
BOOL isMainThread = [[NSThread currentThread] isMainThread];
NSLog(@"%d",isMainThread);
NSLog(@"%@",object);
NSInteger count = 0 ;
for (NSInteger i = 0; i <10000000000; i++) {
count++;
}
NSLog(@"%ld" ,count);
}
2.NSThread实例方法实现多线程
//NSThread实例方法实现多线程
- (IBAction)buttonAction3:(id)sender {
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(thread:) object:IMAGE2_URL];
thread1.name = @"名车";
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(thread:) object:IMAGE1_URL];
thread2.name = @"美女";
//设置线程的优先级,默认是0.5.优先级并不能决定哪条线程先执行,优先级高的线程先执行的概率比较大
thread1.threadPriority = 0.9;
thread2.threadPriority = 0.2;
//开始执行子线程
[thread1 start];
[thread2 start];
}
-(void)thread:(id)object
{
@autoreleasepool {
//实现同步请求网络下载图片
NSLog(@"%@",[NSThread currentThread]);
NSURL *url = [[NSURL alloc]initWithString:object];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
//参数3:是否等showImageOnMainThread:方法执行完毕再往下执行
//系统提供的 返回主线程的方法
[self performSelectorOnMainThread:@selector(showImageOnMainThread:) withObject:image waitUntilDone:YES];
NSLog(@"测试");
}
}
-(void)showImageOnMainThread:(UIImage*)image
{
self.imageView.image = image;
// sleep(3);
}
- (IBAction)buttonAction3:(id)sender {
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(thread:) object:IMAGE2_URL];
thread1.name = @"名车";
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(thread:) object:IMAGE1_URL];
thread2.name = @"美女";
//设置线程的优先级,默认是0.5.优先级并不能决定哪条线程先执行,优先级高的线程先执行的概率比较大
thread1.threadPriority = 0.9;
thread2.threadPriority = 0.2;
//开始执行子线程
[thread1 start];
[thread2 start];
}
-(void)thread:(id)object
{
@autoreleasepool {
//实现同步请求网络下载图片
NSLog(@"%@",[NSThread currentThread]);
NSURL *url = [[NSURL alloc]initWithString:object];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
//参数3:是否等showImageOnMainThread:方法执行完毕再往下执行
//系统提供的 返回主线程的方法
[self performSelectorOnMainThread:@selector(showImageOnMainThread:) withObject:image waitUntilDone:YES];
NSLog(@"测试");
}
}
-(void)showImageOnMainThread:(UIImage*)image
{
self.imageView.image = image;
// sleep(3);
}
3.NSThread类方法实现多线程
//NSThread类方法实现多线程
- (IBAction)buttonAction4:(id)sender {
//通过类方法创建的子线程会自动开始执行
- (IBAction)buttonAction4:(id)sender {
//通过类方法创建的子线程会自动开始执行
[NSThread detachNewThreadSelector:@selector(thread:) toTarget:self withObject:IMAGE1_URL];
}
4. NSOperationQueue操作队列实现多线程
1.// 先创建操作对象
//操作对象本身没有主线程和子线程之分,在哪个线程中都可以执行
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationAction:) object:IMAGE1_URL];
// [invocationOperation start];
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationAction:) object:IMAGE1_URL];
// [invocationOperation start];
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
NSURL *url = [[NSURL alloc]initWithString:IMAGE2_URL];
NSData *data = [NSData dataWithContentsOfURL:url];
NSLog(@"%@",[NSThread currentThread]);
NSURL *url = [[NSURL alloc]initWithString:IMAGE2_URL];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
[self performSelectorOnMainThread:@selector(showImageOnMainThread:) withObject:image waitUntilDone:NO];
}];
2.创建操作队列 ,将操作对象加入到操作队列中,实现多线程
//操作队列 NSOperationQueue 将操作对象加入到操作队列中,实现多线程
NSOperationQueue *oq = [[NSOperationQueue alloc]init];
// 最大并发数,能够同时执行的任务
oq.maxConcurrentOperationCount = 1;
//将操作对象加入到操作队列中之后,操作队列会开辟合适数量的线程来执行操作
[oq addOperation:invocationOperation];
[oq addOperation:blockOperation];
[oq addOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
NSURL *url = [[NSURL alloc]initWithString:IMAGE1_URL];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
[self performSelectorOnMainThread:@selector(showImageOnMainThread:) withObject:image waitUntilDone:NO];
oq.maxConcurrentOperationCount = 1;
//将操作对象加入到操作队列中之后,操作队列会开辟合适数量的线程来执行操作
[oq addOperation:invocationOperation];
[oq addOperation:blockOperation];
[oq addOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
NSURL *url = [[NSURL alloc]initWithString:IMAGE1_URL];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
[self performSelectorOnMainThread:@selector(showImageOnMainThread:) withObject:image waitUntilDone:NO];
}];
//主队列,主队列就一条线程--主线程
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[mainQueue addOperation:invocationOperation];
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[mainQueue addOperation:invocationOperation];
[mainQueue addOperation:blockOperation];
-(void)invocationAction:(id)object
{
NSLog(@"%@",[NSThread currentThread]);
NSURL *url = [[NSURL alloc]initWithString:object];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
//在子线程中执行操作对象,必须要写这句
//系统提供的 返回主线程的方法
[self performSelectorOnMainThread:@selector(showImageOnMainThread:) withObject:image waitUntilDone:NO];
{
NSLog(@"%@",[NSThread currentThread]);
NSURL *url = [[NSURL alloc]initWithString:object];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
//在子线程中执行操作对象,必须要写这句
//系统提供的 返回主线程的方法
[self performSelectorOnMainThread:@selector(showImageOnMainThread:) withObject:image waitUntilDone:NO];
}
5.GCD(Grand Center Dispatch)大中央调度 以队列的方式管理多线程
//GCD Grand Center dispatch 大中央调度 以队列的方式管理多线程
- (IBAction)buttonAction6:(id)sender {
//获取系统的串行队列
{
dispatch_queue_t serialQueue = dispatch_get_main_queue();
// 向某个队列中添加子线程
// 参数1: 队列
// 参数2:添加的子线程中执行什么代码
// 如果该队列是系统的主队列,是无法添加子线程,block中的代码是在主线程中执行
dispatch_async(serialQueue, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
//创建串行队列
{
//参数1: 队列的名字
//参数2:要创建的队列的类型
dispatch_queue_t serialQueue = dispatch_queue_create("hehe", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
for (int i = 0; i < 10; i++) {
NSLog(@"he");
}
});
dispatch_async(serialQueue, ^{
for (int i = 0; i < 10; i++) {
NSLog(@"ha");
}
});
}
// 获取系统的并行队列
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
//创建并行队列
{
dispatch_queue_t concurrentQueue = dispatch_queue_create("haha", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue, ^{
dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 10; i++) {
NSLog(@"嘿");
}
});
dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 10; i++) {
NSLog(@"呵");
}
});
});
//获取系统的串行队列
{
dispatch_queue_t serialQueue = dispatch_get_main_queue();
// 向某个队列中添加子线程
// 参数1: 队列
// 参数2:添加的子线程中执行什么代码
// 如果该队列是系统的主队列,是无法添加子线程,block中的代码是在主线程中执行
dispatch_async(serialQueue, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
//创建串行队列
{
//参数1: 队列的名字
//参数2:要创建的队列的类型
dispatch_queue_t serialQueue = dispatch_queue_create("hehe", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
for (int i = 0; i < 10; i++) {
NSLog(@"he");
}
});
dispatch_async(serialQueue, ^{
for (int i = 0; i < 10; i++) {
NSLog(@"ha");
}
});
}
// 获取系统的并行队列
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
//创建并行队列
{
dispatch_queue_t concurrentQueue = dispatch_queue_create("haha", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue, ^{
dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 10; i++) {
NSLog(@"嘿");
}
});
dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 10; i++) {
NSLog(@"呵");
}
});
});
}
}