• 线程问题


    1、一定要在主线程中更新UI

    1、在子线程中是不能进行UI 更新的,而可以更新的结果只是一个幻像:因为子线程代码执行完毕了,又自动进入到了主线程,执行了子线程中的UI更新的函数栈,这中间的时间非常的短,就让大家误以为分线程可以更新UI。如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新


    2、只有极少数的UI能,因为开辟线程时会获取当前环境,如点击某个按钮,这个按钮响应的方法是开辟一个子线程,在子线程中对该按钮进行UI 更新是能及时的,如换标题,换背景图,但这没有任何意义.(http://blog.csdn.net/shave_kevin/article/details/42713617)

    2、GCD

    一、下面来看下如何使用gcd编程的异步 Objective-c代码

    1. dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
    2. // 处理耗时操作的代码块... 
    3. //通知主线程刷新 
    4. dispatch_async(dispatch_get_main_queue(), ^{ 
    5. //回调或者说是通知主线程刷新, 
    6. }); 
    7. });
    复制代码


    dispatch_async开启一个异步操作,第一个参数是指定一个gcd队列,第二个参数是分配一个处理事物的程序块到该队列。 
    dispatch_get_global_queue(0, 0),指用了全局队列。 
    一般来说系统本身会有3个队列。 
    global_queue,current_queue,以及main_queue. 
    获取一个全局队列是接受两个参数,第一个是我分配的事物处理程序块队列优先级。分高低和默认,0为默认2为高,-2为低 
    Objective-c代码

    1. #define DISPATCH_QUEUE_PRIORITY_HIGH     2  
    2. #define DISPATCH_QUEUE_PRIORITY_DEFAULT  0  
    3. #define DISPATCH_QUEUE_PRIORITY_LOW     (-2) 
    复制代码


    处理完事物后,需要将结果返回给或者是刷新UI主线程,同样,和上面一样,抓取主线程,程序块操作。 

    二、GCD之并发概念 

    其实对于编程中,我们一直提及到的几个概念,同步,异步,并发,锁等。 
    有时觉得一下子还真说不清。 

    下面我们以上面提到的图片加载来看下这3个概念我的理解 


    1同步:


    Objective-c代码

    1. for (int i = 0 ; i < 10; i++) {  
    2.      
    3.       UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];  
    4.        [myImgV[i] setImage:img];  
    5.        
    6. }
    复制代码


    假设我要加载10个图片,我现在拥有这些图片的资源地址,保存在一个数组中。 
    我们先以获取第一张图片来举例: 
    同步执行的概念就是,我获取完第一张图片的, 
    执行了for循环第一句返回了img后,我才能执行第二句,UI界面的刷新。 
    如果第一句返回的时间需要10秒,那我程序的响应就仿佛一直卡在这里一样,我无法进行其他操作。必须等它返回!! 
    因此,同步的一个很好理解的感念就是,一步走到黑。 

    2.异步 

    1. for (int i = 0 ; i < 10; i++) {  
    2.       dispatch_async(dispatch_get_global_queue(0, 0), ^{  
    3.       // 处理耗时操作的代码块...  
    4.        UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];  
    5.       //通知主线程刷新  
    6.       dispatch_async(dispatch_get_main_queue(), ^{  
    7.           //回调或者说是通知主线程刷新,  
    8.             [myImgV[i] setImage:img];  
    9.       });  
    10.         
    11.   });

    看了这代码,我们会说,异步操作那个假设还是要10秒啊,总体看来,执行一张图片的时间加载还是要在10秒左右啊, 
    貌似异步没什么鸟用么。但是,别忽略了其中一点,也黑丝核心的一点,此时我们图片获取操作放在里一个线程队列里, 
    此刻,虽然我们看着图片的加载还是需要10秒才会出来,但是,在这10秒期间,我们的UI主线程是可以操作的,优点:比如界面上有个按钮,你是可以按的 
    而不是如上面的同步,在10面期间,我是只能干等着,什么都做不了。 
    异步的核心概念就是一个新线程,一个消息回调通知。 

    3.并发( dispatch_group_async)

    我们还是以上代码为例。前面我强调了,我们只看一张图片的加载,现在,回到我们第一眼看到代码的思维上去,
    一个for循环。其实上面代码过后,我是创建了10个异步线程。 

    同步:不如下一步要用到上一步的数据,应该用到同步

    异步可能是为了解决耗时操作造成的主线程堵塞, 
    同步是为了解决一些不必要错误和麻烦。也许到这里,我们脑中会联想到的所谓的线程安全性。 
    其实同步以及同步锁,却是应该是考虑到这样的不必要和不安全因素。 

    最后在简单阐述下异步和并发关系。 
    其实看了上面说的,异步只是提供了一种多线程处理的概念, 
    并发是更像是异步的一种大规模实现。 
    就好比说,异步提出了可以用小弟去收保护费,收完了告诉并交给自己,而我在期间做其他要做的事。 
    并发突然想到,异步这个很有道理啊,那我有4个地方要收,一个小弟去收,虽然我还是可以闲着做其他的事, 
    但是小弟跑四个地方,我拿到钱所需要的时间还是和我自己去收一样的,只不过我不用那么费劲了,还能做其他事了。 
    因此,并发觉得应该派四个小弟去,因为每个场地的保护费各不相干的。(刚看了个纽约黑帮~)。 

    因此说,异步解决了线程堵塞,而并发则是在异步的基础上,提高了符合特性事件的处理时间效率。 

    当然,如果10个图片本身相互间是没什么联系,但是,最后一个事件需要处理计算这10个图片的总容量值。 
    那么可以用 dispatch_group_async。 
    具体就看文档吧。 

    常用的方法dispatch_async

    为了避免界面在处理耗时的操作时卡死,比如读取网络数据,IO,数据库读写等,我们会在另外一个线程中处理这些操作,然后通知主线程更新界面。

    用GCD实现这个流程的操作比前面介绍的NSThread  NSOperation的方法都要简单。代码框架结构如下:

    1. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
    2.     // 耗时的操作  
    3.     dispatch_async(dispatch_get_main_queue(), ^{  
    4.         // 更新界面  
    5.     });  
    6. });  

    如果这样还不清晰的话,那我们还是用上两篇博客中的下载图片为例子,代码如下:

      1. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
      2.     NSURL * url = [NSURL URLWithString:@"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"];  
      3.     NSData * data = [[NSData alloc]initWithContentsOfURL:url];  
      4.     UIImage *image = [[UIImage alloc]initWithData:data];  
      5.     if (data != nil) {  
      6.         dispatch_async(dispatch_get_main_queue(), ^{  
      7.             self.imageView.image = image;  
      8.          });  
      9.     }  
      10. });  
  • 相关阅读:
    Js:返回上一页
    select设置选中项/select的级联
    js闭包
    bootstrap
    My97DatePicker使用 、layDate 日期与时间组件
    IO流
    java之String工具类和File类
    Python学习之路文件file常用方法
    Python学习之路-集合set的常用方法
    Python学习之路-字典外传
  • 原文地址:https://www.cnblogs.com/dannygao/p/6959039.html
Copyright © 2020-2023  润新知