IOS之多线程

 

一、多线程

1、什么是多线程

NSThread

(1)多线程可以同时处理多个任务的请求。如果要同时执行多个任务,需要开启一个新的线程。程序执行的时候串行执行,如果多个任务执行是并行执行。

  //创建新的线程1
    NSThread *thread1 =[[NSThread alloc]initWithTarget:self selector:@selector(taska:) object:nil];
    [thread1 start];
    //创建新线程2
    [NSThread detachNewThreadSelector:@selector(taskb:) toTarget:self withObject:nil];

(2)多线程能解决什么问题?

//

 本质上,主要是解决某个耗时的任务执行时出现的界面卡死的问题,保证多个任务可以同时执行,比如迅雷下载。

 //

场景使用,如大麦网,有的图片下载耗时5秒,或者加载1G的文件,需要启动多线程。

//

(3) 线程的同步以及锁 演示问题

 CPU从内存中拿出数据更改值然后放回内存,如果多线程访问,结果可能不正确。解决方式是加锁。

-(void)add
{
    for (int i=0; i<1000; i++) {
        [_lock lock];
        _num ++;
        NSLog(@"add ==%d",_num);
        [_lock unlock];
    }
}
-(void)sub
{
    for (int i=0; i<1000; i++) {
        [_lock lock];
        _num --;
        NSLog(@"sub ==%d",_num);
        [_lock unlock];
    }
}

项目开发中,noatomic当一个属性只有UI界面访问可以加,提高访问速度。如果这个属性会被创建的子线程访问时不要加noatomic保证线程的安全。

UI线程称为主线程,其他创建的线程称为工作子线程

注意:不要在子线程中直接操作UI

 

{ .......
///子线程如何更新UI(重要),避免代码出问题。eg:下载进度更新 ///UI线程称为主线程,其他创建的线程称为工作子线程,注意:不要在子线程中直接操作UI(间接让主线程操作UI) _progressView =[[UIProgressView alloc] initWithFrame:CGRectMake(50, 200, 250, 10)]; [self.view addSubview:_progressView]; [NSThread detachNewThreadSelector:@selector(downloadNetworkingData) toTarget:self withObject:nil]; } #pragma mark --演示下载数据 -(void)downloadNetworkingData { //模拟10s网络下载 for (int i=0; i<100; i++) { //_progressView.progress +=0.01;不要在这里操作UI界面 // 以下语句是间接操作UI的过程 [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES]; [NSThread sleepForTimeInterval:0.1]; } } -(void)updateUI {_progressView.progress +=0.01;}

 

二、NSOpetation

1、什么是NSOperation

 也是实现多线程的一种机制,在NSThread做了更高的抽象,加入了Block,比NSThread简单易用

 

三 、GCD

1、Grand Central Dispatch 简写

优点:支持多核心,C和BLOCK接口,易于使用,功能强大。

 

1.创建一个异步任务
   [ self creatAsyncTask];
2.模拟网络下载
    [self simulateNewokingDownload];
3.只是执行一次
  [self runOnce];
 4。延时执行
    [self delayRun];
 5 通知执行多个任务,等待所有任务执行完成时进行处理
    [self groupRun];  
===============

-(void)groupRun
{ //group 任务组
    dispatch_group_t group =dispatch_group_create();
    //添加任务,7秒完成
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //
        for (int i=0; i<100; i++) {
            NSLog(@"A=%d",i);
            [NSThread sleepForTimeInterval:0.07];
        }
        
    });
    //添加任务,5秒完成
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //
        for (int i=0; i<100; i++) {
            NSLog(@"B=%d",i);
            [NSThread sleepForTimeInterval:0.05];
        }
        
    });
    //添加任务,10秒完成
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //
        for (int i=0; i<100; i++) {
            NSLog(@"C=%d",i);
            [NSThread sleepForTimeInterval:0.1];
        }
        
    });
// 监控完成后的操作
    dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       
        NSLog(@"全部任务完成了");
    });
}

-(void)delayRun
{
 //5s后输出
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(5*NSEC_PER_SEC) ), dispatch_get_main_queue(), ^{
        //
        NSLog(@"haha");
    });

}

-(void)runOnce
{
    static dispatch_once_t onceToken;
    
dispatch_once(&onceToken, ^{
    
    NSLog(@"只执行一次的代码");
});

}



-(void)simulateNewokingDownload
{
    _progressView =[[UIProgressView alloc] initWithFrame:CGRectMake(50, 200, 250, 10)];
    [self.view addSubview:_progressView];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      
      for (int i=0; i<10; i++) {
          //
          //最后显示对话框
          
          dispatch_async(dispatch_get_main_queue(), ^{
              
              _progressView.progress +=0.1;
          });
          
          [NSThread sleepForTimeInterval:1];
          
      }
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
            UIAlertView *alertView =[[UIAlertView alloc] init];
            alertView.message =@"下载完成";
            [alertView addButtonWithTitle:@"取消"];
            [alertView show];
        });
  });

}


#pragma mark --GCD测试方法
-(void)creatAsyncTask
{
    //创建一个异步任务,参数1,传入queue,有3种queue: main queue  主队列 ;global queue 全局队列,工作线程;自定义queue
    dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
  dispatch_async(queue, ^{
      for (int i=0; i<20; i++) {
          
          NSLog(@"A===%d",i);
      }

  });
    
    dispatch_async(queue, ^{
        for (int i=0; i<20; i++) {
            
            NSLog(@"B===%d",i);
        }
        
    });


}

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。