让我们一起走进 多线程

前言: 
    //判断当前代码执行的时候是否是在主线程
BOOL isMainThread =  [[NSThread currentThread] isMainThread];
NSLog(@"%d",isMainThread);

主线程阻塞会造成UI冻结,页面假死

例如:
 NSInteger count = 0 ;
    for (int i = 0; i <1000000000; i++) {
        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);
    
}
 
   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);
}

3.NSThread类方法实现多线程

//NSThread类方法实现多线程
- (
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];

    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
       
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];
    }];

//主队列,主队列就一条线程--主线程
   
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];
}


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(@"");
                }
            });
        });
       
    }  
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值