用GCD创建多线程

GCD是苹果推荐的多线程方案,通常应用的场景是当程序需要做复杂的耗时的计算或操作的时候。比如发送网络请求,下载大图片等等。如果将这些都交由主线程来执行,那么主线程将无法响应用户的界面操作,非常影响用户体验。

  这时候,将这些耗时任务交给子线程,就变成非常必要。GCD则是一套由C语言写的库。

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSAssert(_image, @"Image not set; required to use view controller");
    self.photoImageView.image = _image;

    //Resize if neccessary to ensure it‘s not pixelated
    if (_image.size.height <= self.photoImageView.bounds.size.height &&
        _image.size.width <= self.photoImageView.bounds.size.width) {
        [self.photoImageView setContentMode:UIViewContentModeCenter];
    }

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1
        UIImage *overlayImage = [self faceOverlayImageFromImage:_image];
        dispatch_async(dispatch_get_main_queue(), ^{ // 2
            [self fadeInNewImage:overlayImage]; // 3
        });
    });
}

如上面的代码所显示,我们通常复杂任务交了子线程~即是这样:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)

  dispatch_async 为创建一个异步执行的任务,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)之后放在全局队列,也就是一个系统的并行队列。这样,代码则会在子线程中执行,并且保证了线程能顺利执行完。

  而如果采用了住队列,结果则是变为异步就没有得到想要的效果了。最后还是会由主线程来执行任务的。所以需要用到多线程的时候,我们选择的一般是并行队列异步执行。

  而当需要更新界面的时候,有一点必须要注意的是,也就是当需要访问UIkit的时候是必须要在主线程中进行,所以便需要使用:

dispatch_async(dispatch_get_main_queue(), ^{ // 2
            [self fadeInNewImage:overlayImage]; // 3
        });

  上面的代码来回到主线程,完成界面相关操作。但凡需要更新界面,记得拿到住队列~~至于,如果这个地方,我们使用的是 dispatch_sync 后面再回到主线程的话, 会怎么样呢~答案就是阻塞主线程。因为主线程时刻都在执行任务,而我们突然加入一个同步执行的任务到住队列,则主线程正在执行的任务,和这个加上的任务互相等待,造成死锁了。~~所以无论如何,必须要记得,不能够使用主队列/串行队列同步执行了!!

//dispatch_syn(dispatch_get_main_queue(), ^{
        //NSLog(@"3");
        //死锁原因
        //1:dispatch_sync在等待block语句执行完成,而block语句需要在主线程里执行,所以dispatch_sync如果在主线程调用就会造成死锁
        //2:dispatch_sync是同步的,本身就会阻塞当前线程,也即主线程。而又往主线程里塞进去一个block,所以就会发生死锁。
    //});

多线程相关好文章:https://github.com/nixzhu/dev-blog/blob/master/2014-04-19-grand-central-dispatch-in-depth-part-1.md         http://www.jianshu.com/p/0b0d9b1f1f19          http://www.jianshu.com/p/d3f954582231
时间: 2024-10-18 11:53:05

用GCD创建多线程的相关文章

【iOS开发-多线程】使用GCD创建多线程(iOS常用技术)

GCD 全称是Grand Central Dispatch 特点: 自动利用CPU的多核技术 自动管理线程的生命周期 使用步骤 定制任务 将任务添加队列 各类队列的特点 关于同步和异步的两种执行方式 /** * 同步方式执行任务,不管是什么队列,都不会再开一个线程 */ dispatch_sync(<#dispatch_queue_t queue#>, ^{ <#code#> }) /** * 异步方式执行任务,除了主队列都会开启一个新线程 */ dispatch_async(&l

iOS开发中GCD在多线程方面的理解

GCD为Grand Central Dispatch的缩写. Grand Central Dispatch (GCD)是Apple开发的一个多核编程的较新的解决方法.在Mac OS X 10.6雪豹中首次推出,并在最近引入到了iOS4.0. GCD是一个替代诸如NSThread等技术的很高效和强大的技术.GCD完全可以处理诸如数据锁定和资源泄漏等复杂的异步编程问题. GCD可以完成很多事情,但是这里仅关注在iOS应用中实现多线程所需的一些基础知识. 在开始之前,需要理解是要提供给GCD队列的是代

创建多线程类

# -*- coding: cp936 -*- #python 27 #xiaodeng #http://www.cnblogs.com/fnng/p/3489321.html #创建多线程类 import threading from time import sleep,ctime class MyThread(threading.Thread):#threading.Thread '创建MyThread类,用于继承threading.Thread类.' def __init__(self,f

Java多线程开发系列之二:如何创建多线程

前文已介绍过多线程的基本知识了,比如什么是多线程,什么又是进程,为什么要使用多线程等等. 在了解了软件开发中使用多线程的基本常识后,我们今天来聊聊如何简单的使用多线程. 在Java中创建多线程的方式有两种: (1)写一个子类,这个类要继承自Thread类,于此同时这个子类必须要重写Thread类中的run方法(原因我后文中会提到),然后我们就可以用这个类来创建出一个多线程. (2)仍然是写一个类,这个类要实现Runnable接口,与(1)相同,在这个实现类中也需要重写run方法. 这里有一点要注

Qt多线程学习:创建多线程

[为什么要用多线程?] 传统的图形用户界面应用程序都仅仅有一个运行线程,而且一次仅仅运行一个操作.假设用户从用户界面中调用一个比較耗时的操作,当该操作正在运行时,用户界面一般会冻结而不再响应.这个问题能够用事件处理和多线程来解决. [Linux有线程的概念吗?] 传统的UNIX系统也支持线程的概念,但一个进程里仅仅同意有一个线程,这样多线程就是多进程.Linux下的Posix线程(pthreads)是一种轻量级的进程的移植性实现,线程的调度由内核完毕,每一个线程都有自己的编号.假设使用线程,整体

apple平台下的objc的GCD,多线程编程就是优雅自然。

在apple的操作系统平台里,GCD使得多线程编程是那么的优雅自然.在传统的多线程编程中,首先要写线程处理循环:之后还有事件队列,消息队列:还要在线程循环中分离事件解释消息,分派处理:还要考虑线程间是否要同步:还要写许多有着可能费解的函数名的回调处理程序,注册回调程序,而且代码分散即使同一文件也不容易看出与哪些线程对应或者彼此间的是否有次序或并发的关系,不利于调试:另外还要考虑是否需要使用线程池,线程线使用何种模式等.在apple平台的objc中,只需要如下: A* a; dispatch_as

java用Thread方式创建多线程

进程:一个正在执行的程序,每一个进程都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元.线程:进程中一个独立的控制单元.线程控制着进程的执行.一个进程中至少有一个线程. java VM中至少有一个线程负责java程序的执行.而且这个线程运行的代码存在于main方法中.该线程为主线程. 扩展,jvm启动了两个线程,一个主线程,一个垃圾回收机制的线程. 1.怎样创建一个多线程?第一种方法:通过继承Thread类的方法 1.继承Thread类 2.重写Thread类的run()方法 目的:将自

java创建多线程方法之间的区别

我们知道java中创建多线程有两种方法(详见http://blog.csdn.net/cjc211322/article/details/24999163).那么两者有什么区别呢? 一.情形一 code1 /** * ThreadTestDemo.java * @author cjc * */ public class ThreadTestDemo { public static void main(String[] args) { Ticket t=new Ticket(); t.start(

使用_beginThreadex创建多线程(C语言版多线程)

_beginThreadex创建多线程解读 一.需要的头文件支持 #include <process.h>         // for _beginthread() 需要的设置:ProjectàSetting-->C/C++-->User run-time library 选择Debug Multithreaded 或者Multithreaded.即使用: MT或MTD. 源码如下: #include <stdio.h> #include <string>