前言:下面就不一一列出 pthread、NSThread、GCD、NSOperation 的完整的各种方法了,只分别将最常用的列出来,以便偶尔瞄一眼。

一、NSThread

1> 线程间的通讯
/** 这个例子为在创建的子线程中下载图片,然后回到主线程中设置图片 ( 更新UI ) */
- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 隐式创建并启动线程
    [self performSelectorInBackground:@selector(download) withObject:nil];
}

/**
 *  图片下载
 */
- (void)download
{
    NSLog(@"download---%@", [NSThread currentThread]);
    // 1.图片地址
    NSString *urlStr = @"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg";
    NSURL *url = [NSURL URLWithString:urlStr];
    
    // 2.根据地址下载图片的二进制数据(耗时的代码)
    NSLog(@"---begin");
    NSData *data = [NSData dataWithContentsOfURL:url];
    NSLog(@"---end");
    
    // 3.设置图片
    UIImage *image = [UIImage imageWithData:data];
    
    // 4.回到主线程,刷新UI界面(为了线程安全)
    [self performSelectorOnMainThread:@selector(downloadFinished:) withObject:image waitUntilDone:NO];
//    [self performSelector:@selector(downloadFinished:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
//    [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
    
    NSLog(@"-----over----");
}

- (void)downloadFinished:(UIImage *)image
{
    self.imageView.image = image;
    
    NSLog(@"downloadFinished---%@", [NSThread currentThread]);
}
@end
/****************************分割线****************************/

二、GCD

1> 、GCD    【 (任务)同步/异步***(队列)串行/并发*****任务和队列的几种组合方式 】
- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self asyncSerialQueue];
}

// 就下面三个最常用,(GCD中其他情况不要管)
/**

* 第一种组合方式
 *  async -- 并发队列(最常用)
 *  会不会创建线程:会,一般同时开多条
 *  任务的执行方式:并发执行
 */
- (void)asyncGlobalQueue
{
    // 获得全局的并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 将 任务 添加 全局队列 中去 异步 执行
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
    });
}
/**
 *第一种组合方式 打印结果
 2016-04-07 17:48:05.007 Test-GCD测试一下[909:50754] -----下载图片2---<NSThread: 0x7f8acb50ea50>{number = 3, name = (null)}
 2016-04-07 17:48:05.007 Test-GCD测试一下[909:50755] -----下载图片1---<NSThread: 0x7f8acb4bedf0>{number = 2, name = (null)}
 2016-04-07 17:48:05.007 Test-GCD测试一下[909:50762] -----下载图片4---<NSThread: 0x7f8acb71b570>{number = 5, name = (null)}
 2016-04-07 17:48:05.007 Test-GCD测试一下[909:50763] -----下载图片5---<NSThread: 0x7f8acb510160>{number = 6, name = (null)}
 2016-04-07 17:48:05.007 Test-GCD测试一下[909:50758] -----下载图片3---<NSThread: 0x7f8acb60e780>{number = 4, name = (null)}
 */

/**

* 第二种组合方式
 *  async -- 串行队列(有时候用)
 *  会不会创建线程:会,一般只开1条线程
 *  任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务)
 */
- (void)asyncSerialQueue
{
    // 1.创建一个串行队列
    dispatch_queue_t queue = dispatch_queue_create("cn.heima.queue", NULL);
    
    // 2.将任务添加到串行队列中 异步 执行
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
    });
    
    // 3.非ARC,需要释放创建的队列
//    dispatch_release(queue);
}

/**

* 第二种方式 打印结果
 2016-04-07 17:49:33.730 Test-GCD测试一下[921:52233] -----下载图片1---<NSThread: 0x7f926ad09e20>{number = 2, name = (null)}
 2016-04-07 17:49:33.731 Test-GCD测试一下[921:52233] -----下载图片2---<NSThread: 0x7f926ad09e20>{number = 2, name = (null)}
 2016-04-07 17:49:33.731 Test-GCD测试一下[921:52233] -----下载图片3---<NSThread: 0x7f926ad09e20>{number = 2, name = (null)}
 2016-04-07 17:49:33.731 Test-GCD测试一下[921:52233] -----下载图片4---<NSThread: 0x7f926ad09e20>{number = 2, name = (null)}
 2016-04-07 17:49:33.731 Test-GCD测试一下[921:52233] -----下载图片5---<NSThread: 0x7f926ad09e20>{number = 2, name = (null)}
 */

/**

* 第三种方式 (这是一种特殊的方式,将 任务 添加到主队列中 异步 执行)
 *  async -- 主队列(很常用)     (一般在线程之间的通讯才用得上 @xz)
 */
- (void)asyncMainQueue
{
    // 1.主队列(添加到主队列中的任务,都会自动放到主线程中去执行)
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    // 2.添加 任务 到主队列中 异步 执行
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
    });
}

/**

* 第三种方式 打印结果如下:

2016-04-07 16:50:04.245 Test-GCD测试一下[801:31778] -----下载图片1---<NSThread: 0x7fb2a2d0a1e0>{number = 1, name = main}
2016-04-07 16:50:04.246 Test-GCD测试一下[801:31778] -----下载图片2---<NSThread: 0x7fb2a2d0a1e0>{number = 1, name = main}
2016-04-07 16:50:04.246 Test-GCD测试一下[801:31778] -----下载图片3---<NSThread: 0x7fb2a2d0a1e0>{number = 1, name = main}
2016-04-07 16:50:04.247 Test-GCD测试一下[801:31778] -----下载图片4---<NSThread: 0x7fb2a2d0a1e0>{number = 1, name = main}
2016-04-07 16:50:04.248 Test-GCD测试一下[801:31778] -----下载图片5---<NSThread: 0x7fb2a2d0a1e0>{number = 1, name = main}

*/

2> GCD------线程间通讯示例

注意点:
<1>.  需要设置按钮的image和backgroundImage,建议先把按钮类型改为custom,才能保证设置成功
<2>.  属性名不能以new开头
<3>.  只有在init开头的构造方法中,才允许对self进行赋值

#define XZGlobalQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define XZMainQueue dispatch_get_main_queue()

#import "XZViewController.h"

@interface XZViewController ()
@property (weak, nonatomic) IBOutlet UIButton *button;
@end

@implementation XZViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(20, 20, 100, 60)];
        [self.view addSubview:button];
        self.button = button;

dispatch_async(XZGlobalQueue, ^{
        NSLog(@"donwload---%@", [NSThread currentThread]);
        // 1.子线程下载图片
        NSURL *url = [NSURL URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:data];
        
        // 2.回到主线程设置图片
        dispatch_async(XZMainQueue, ^{
            NSLog(@"setting---%@ %@", [NSThread currentThread], image);
            [self.button setImage:image forState:UIControlStateNormal];
        });
    });
}

@end

/*

* 打印结果

Test-GCD测试一下[873:44012] donwload---<NSThread: 0x7fc7a0401d50>{number = 2, name = (null)}
Test-GCD测试一下[873:43920] setting---<NSThread: 0x7fc7a0507930>{number = 1, name = main} <UIImage: 0x7fc7a0681530>, {440, 608}

*/
/****************************分割线****************************/

iOS-多线程--介绍NSThread和GCD及其它们的线程通讯示例的更多相关文章

  1. iOS多线程开发--NSThread NSOperation GCD

    多线程 当用户播放音频.下载资源.进行图像处理时往往希望做这些事情的时候其他操作不会被中 断或者希望这些操作过程中更加顺畅.在单线程中一个线程只能做一件事情,一件事情处理不完另一件事就不能开始,这样势 ...

  2. iOS 多线程(NSThread、GCD、NSOperation)

    ios中得多线程技术主要使用3种:NSThread.NSOperation和GCD 一.NSThread: 最轻量级方法,但是不安全需要手动加锁,需要自己管理生命周期 NSThread的使用方法有2种 ...

  3. iOS的三种多线程技术NSThread/NSOperation/GCD

    1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的"并发"技术,使得程序员可以不再去关心 ...

  4. 多线程技术 NSThread & NSOperation & GCD

    多线程:在iOS开发中,用到多线程的处理问题的时候有很多,比如异步下载数据时刷新界面等等. 引入多线程来处理问题的关键就是,基于多线程可以使界面更加流畅,防止界面假死. 界面假死:比如你单击一个按钮来 ...

  5. iOS多线程(上)——GCD详解(上)

    GCD(Grand central Dispatch)是Apple开发的一个多核编程的较新的解决方法.它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统.下面我讲讲述关于GCD的点,通篇读完 ...

  6. iOS 多线程之 NSThread的基本使用

    一个NSThread对象就代表一条线程 下面是NSThread开启线程的方法 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEv ...

  7. IOS多线程(NSThread)

    1.创建方法 使用NSThread创建线程主要有两个个方法,分别如下 NSThread* myThread = [[NSThread alloc] initWithTarget:self   sele ...

  8. iOS多线程介绍

    一.线程概述 有些程序是一条直线,起点到终点:有些程序是一个圆,不断循环,直到将它切断.直线的如简单的Hello World,运行打印完,它的生命周期便结束了,像昙花一现那样:圆如操作系统,一直运行直 ...

  9. 多线程&NSObject&NSThread&NSOperation&GCD

    1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题 2.NSOperation/NS ...

随机推荐

  1. 在 ubuntu 下安装 apache 和 mod_mono ,并测试

    1. 保证 ubuntu 能联网. 2. 打开终端,输入:sudo apt-get install apache2 3. 安装完 apache2 后,打开浏览器,输入:http://localhost ...

  2. undefined symbol libiconv_open 完全解决方案

    我在另一篇关于Ubuntu+Sendmail+Dovecot+Openwebmail 邮件服务器搭建完全解决方案文章完成后,我的邮件服务器也搭建完成了, 事实上也正在运行中, 但是有网友依据我的操作步 ...

  3. epoll源码实现分析[整理]

    epoll用法回顾 先简单回顾下如何使用C库封装的3个epoll相关的系统调用.更详细的用法参见http://www.cnblogs.com/apprentice89/archive/2013/05/ ...

  4. Git 版本管理

    应用情景1:添加文件(单个.多个.目录)到Git版本库,提交一个版本快照. 应用情景2:穿越历史回到过去,版本回退,从当前版本回退到之前提交过的某个版本上. 应用情景3:穿越历史过头了,版本回退多了, ...

  5. 清除WebLogic8.1缓存

    在Domain目录下面有一个以server命名的文件夹,删除整个文件夹就可以了.

  6. 使用Kibana 分析Nginx 日志并在 Dashboard上展示

    一.Kibana之Visualize 功能 在首页上Visualize 标签页用来设计可视化图形.你可以保存之前在discovery中的搜索来进行画图,然后保存该visualize,或者加载合并到 d ...

  7. 一起Polyfill系列:Function.prototype.bind的四个阶段

    昨天边参考es5-shim边自己实现Function.prototype.bind,发现有不少以前忽视了的地方,这里就作为一个小总结吧. 一.Function.prototype.bind的作用 其实 ...

  8. 微信公众平台入门开发教程.Net(C#)框架

    一.序言 一直在想第一次写博客,应该写点什么好?正好最近在研究微信公众平台开发,索性就记录下,分享下自己的心得,也分享下本人简单模仿asp.net运行机制所写的通用的微信公众平台开发.Net(c#)框 ...

  9. C#调用webservice 时如何传递实体对象

    在webservice端公开一个实体类,然后实例化,赋值,然后再给到webservice,可以实现,但是,即使调用端和service端的实体类完全一致,你也要重新实例化service端的,重新赋值,将 ...

  10. 【Bootstrap基础学习】04 Bootstrap的HTML和CSS编码规范

    HTML 用两个空格来代替制表符(tab) -- 这是唯一能保证在所有环境下获得一致展现的方法. 嵌套元素应当缩进一次(即两个空格) 对于属性的定义,确保全部使用双引号,绝不要使用单引号. 不要在自闭 ...