zoukankan      html  css  js  c++  java
  • 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);
            }
            
        });
    
    
    }
  • 相关阅读:
    几个常见移动平台浏览器的User-Agent
    正则表达式那些事儿(三)
    正则表达式那些事儿(二)
    正则表达式那些事儿(一)
    jQuery官网plugins栏目下那些不错的插件
    UVA 11729 Commando War 突击战 【贪心】
    HDOJ 2084 数塔 【dp】
    HDOJ 1465 不容易系列之一 【错排公式 递推】
    HDOJ 2046 骨牌铺方格 【递推】
    HDOJ 2044 一只小蜜蜂... 【递推】
  • 原文地址:https://www.cnblogs.com/jayzhang/p/4427701.html
Copyright © 2011-2022 走看看