iOS:多线程技术GCD的使用

GCD的使用:

1.队列的类型
     1.1 主队列:mian queue,主线程队列,负责更行UI的操作。是一个串行的队列。
     1.2 系统默认的并行队列:global queue,按优先级分类。
     1.3 自定义的队列:可以创建串行队列或者是并行的队列
 
2.任务
     2.1 封装的形式:block方法或C语言的函数
     2.2 添加到队列的方式:同步或异步(只对并行队列有区别)
         例如服务器请求:
         同步:提交请求->等待服务器处理(这个期间客户端浏览器不能干任何事)->处理完毕返回   
         异步:请求通过事件触发->服务器处理(这个期间客户端浏览器仍可以干其他的事)->处理完毕返回
 
3.特殊使用
     3.1 只执行一次 dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);(多用于单例模式)
     3.2 延时执行    dispatch_after(dispatch_time_t when,dispatch_queue_t  queue,dispatch_block_t block);
     3.3 成组的执行任务       dispatch_group_create(void);
     3.4 创建自定义的队列    dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
     3.5 创建默认的全局队列 dispatch_get_global_queue(long identifier, unsigned long flags)
     3.6 获取主队列             dispatch_get_main_queue(void)
     3.7 异步执行                dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
     3.8 同步执行              dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
     3.9 多次执行  dispatch_apply(size_t iterations, dispatch_queue_t queue,void (^block)(size_t));
     …………………等等…………………

4.几个方法参数解释:

<1>创建自定义的队列    dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);

const char *label:队列名字                   dispatch_queue_attr_t attr:队列执行方式(串行、并行)

<2>创建默认的全局队列 dispatch_get_global_queue(long identifier, unsigned long flags)

long identifier:队列执行的优先级           unsigned long flags:默认为0即可

<3>多次执行         dispatch_apply(size_t iterations, dispatch_queue_t queue,void (^block)(size_t));

size_t iterations:执行次数      dispatch_queue_t queue:队列      void (^block)(size_t):block函数块

 
5.队列方式宏定义(用于创建自定义队列时的参数)

#define DISPATCH_QUEUE_SERIAL NULL         //串行

#define DISPATCH_QUEUE_CONCURRENT        //并行

 

6.队列优先级宏定义(创建全局队列时的参数)

#define DISPATCH_QUEUE_PRIORITY_HIGH 2

#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0

#define DISPATCH_QUEUE_PRIORITY_LOW (-2)

#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN

 

7.更能区分

主队列:专门用来执行主线程的,进行UI的更新操作

全局队列或自定义队列:用来添加并执行其他的线程,进行数据的操作

 

 具体举例如下:

例子1:采用不分组的方式,将多线程添加到队列中,然后进行多线程的操作。

1.准备UI界面布局:拖入一个文本视图控件,并关联相关的类中,同时在类中声明一个票数变量

复制代码
@interface ViewController ()
{NSInteger _tickets;
}
@property (weak, nonatomic) IBOutlet UITextView *textView;
@end
复制代码

2.设置票数,同时将原来文本视图中默认的数据清空,取消自动布局便于后面添加数据时自动滚动文本视图

 //设置数据和文本视图_tickets = 20;[self.textView setText:@""];self.textView.layoutManager.allowsNonContiguousLayout = NO;

3.创建全局队列,并设置优先级,设置并行方式

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

4.用GCD创建任务线程,并将线程添加到队列中,采用异步执行方式

复制代码
dispatch_async(queue, ^{[self GCDSellTicketMethod:@"GCD售票线程-1"];});dispatch_async(queue, ^{[self GCDSellTicketMethod:@"GCD售票线程-2"];});
复制代码

5.定义更新UI的方法

#pragma mark -更新UI的操作

复制代码
-(void)appendTextView:(NSString *)text
{//1.获取原来的数据NSMutableString *content = [NSMutableString stringWithString:self.textView.text];NSRange range = NSMakeRange(content.length, 2);//2.追加新的内容[content appendString:[NSString stringWithFormat:@"\n%@",text]];[self.textView setText:content];//3.滚动视图
    [self.textView scrollRangeToVisible:range];
}
复制代码

6.定义任务线程的执行方法

#pragma mark -执行线程的操作

复制代码
-(void)GCDSellTicketMethod:(NSString *)name
{while (YES){if(_tickets > 0){//使用GCDdispatch_async(dispatch_get_main_queue(), ^{//更新UINSString *info = [NSString stringWithFormat:@"总票数:%ld,当前的线程:%@",_tickets,name];[self appendTextView:info];//卖票_tickets--;});//线程休眠if([name isEqualToString:@"GCD售票线程-1"]){[NSThread sleepForTimeInterval:0.3f];}else{[NSThread sleepForTimeInterval:0.2f];}}else{//使用GCD更新UIdispatch_async(dispatch_get_main_queue(), ^{NSString *info = [NSString stringWithFormat:@"票已经卖完,当前线程:%@",name];[self appendTextView:info];});//退出线程break;}}
}
复制代码

 

例子2:采用分组的方式,将线程组添加到队列中,然后进行多线程的操作。

1.准备UI界面布局:拖入一个文本视图控件,并关联相关的类中,同时在类中声明一个票数变量

复制代码
@interface ViewController ()
{NSInteger _tickets;
}
@property (weak, nonatomic) IBOutlet UITextView *textView;
@end
复制代码

2.设置票数,同时将原来文本视图中默认的数据清空,取消自动布局便于后面添加数据时自动滚动文本视图

 //设置数据和文本视图_tickets = 20;[self.textView setText:@""];self.textView.layoutManager.allowsNonContiguousLayout = NO;

3.创建一个线程分组

dispatch_group_t group = dispatch_group_create();

4.创建自定义的队列,并设置队列执行方式为并行方式

  dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);

5.用GCD创建任务线程组,并将线程组添加到队列中,采用分组异步执行方式

复制代码

  dispatch_group_async(group,queue, ^{

      [self GCDSellTicketMethod:@"GCD售票线程-1"];

  });   

  dispatch_group_async(group,queue, ^{

      [self GCDSellTicketMethod:@"GCD售票线程-2"];

  });

复制代码

6.等线程组中的所有任务完成后,会接收到通知,更新UI

复制代码
dispatch_group_notify(group, queue, ^{dispatch_async(dispatch_get_main_queue(), ^{NSString *info = [NSString stringWithFormat:@"票已经卖完"];[self appendTextView:info];});});
复制代码

7.定义更新UI的方法

#pragma mark -更新UI的操作

复制代码
-(void)appendTextView:(NSString *)text
{//1.获取原来的数据NSMutableString *content = [NSMutableString stringWithString:self.textView.text];NSRange range = NSMakeRange(content.length, 2);//2.追加新的内容[content appendString:[NSString stringWithFormat:@"\n%@",text]];[self.textView setText:content];//3.滚动视图[self.textView scrollRangeToVisible:range];
}
复制代码

8.定义任务线程的执行方法

#pragma mark -执行线程的操作

复制代码
-(void)GCDSellTicketMethod:(NSString *)name
{while (YES){if(_tickets > 0){//使用GCDdispatch_async(dispatch_get_main_queue(), ^{//更新UINSString *info = [NSString stringWithFormat:@"总票数:%ld,当前的线程:%@",_tickets,name];[self appendTextView:info];//卖票_tickets--;});//线程休眠if([name isEqualToString:@"GCD售票线程-1"]){[NSThread sleepForTimeInterval:0.3f];}else{[NSThread sleepForTimeInterval:0.2f];}}else{     //退出线程break;}}
}
复制代码

 

两种情况的演示结果如下:

 

 

 

 

 

 

 

程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!
分类: iOS高级

本文转自当天真遇到现实博客园博客,原文链接:http://www.cnblogs.com/XYQ-208910/p/4859089.html,如需转载请自行联系原作者

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395624.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java什么叫一致性,java-顺序一致性易失性说明

我正在从Java Jpoint会议观看视频.我对以下来自Alexey Shipilev报告的幻灯片有疑问&#xff1a;打扰一下,请不要打扰我.实际上,作者说不可能将变量集设置为r1 1 (Y)r2 0 (x)r3 1 (x)r4 0 (Y)根据视频,他暗示很明显.有人可以澄清为什么JMM无法设置此值吗&#xff1f;附言如果…

【c++】string类的使用

目录 一、标准库中的string类 1、简单介绍string类 2、string类的常用接口注意事项 2.1、string类对象的常用构造 2.2、string类对象的容量操作 2.3、string类对象的访问及遍历操作 2.4、string类对象的修改操作 二、string类的模拟实现 一、标准库中的string类 1、简…

Java - 对象(object) 具体解释

对象(object) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24059545 对象(object)的实例能够是 物理对象(如 人, 车等实物) 或 逻辑对象(如 运动, 健康等); 对象是将状态(数据) 和行为(功能) 组合在一起的软件模块. 类是描写叙述一组相似对象共同…

c/c++ 重载运算符 函数调用运算符

重载运算符 函数调用运算符 把一个类的对象a&#xff0c;当成函数来使用&#xff0c;比如a()&#xff0c;所以需要重载operator()方法。重载了函数调用运算符的类的对象&#xff0c;就是函数对象了。 还有什么是函数对象呢&#xff1f;&#xff1f;&#xff1f; lambda是函数对…

matlab 万能,matlab 万能实用的线性曲线拟合方法

在科学计算和工程应用中&#xff0c;经常会遇到需要拟合一系列的离散数据&#xff0c;最近找了很多相关的文章方法&#xff0c;在这里进行总结一下其中最完整、几乎能解决所有离散参数线性拟合的方法第一步&#xff1a;得到散点数据根据你的实际问题得到一系列的散点例如&#…

mysql函数之SUBSTRING_INDEX(str,/,-1)

SUBSTRING_INDEX的用法&#xff1a; •SUBSTRING_INDEX(str,delim,count) 在定界符 delim 以及count 出现前&#xff0c;从字符串str返回自字符串。若count为正值,则返回最终定界符(从左边开始) 若为-1则是从后往前截取 SELECT substring_index(Hn_P00001, P, -1) -- 结果是…

第十二章 Shell脚本编写及常见面试题(三)

本章目录&#xff1a;12.21 FTP下载文件#!/bin/bash if [ $# -ne 1 ]; thenecho "Usage: $0 filename" fi dir$(dirname $1) file$(basename $1) ftp -n -v << EOF # -n 自动登录 open 192.168.1.10 user admin adminpass binary # 设置ftp传输模式为二进制…

省选前的考试记录

日拱一卒功不唐捐 什么沙雕玩意儿 2018.12.24 T1 如果对 \(A\) 数组求出来高度递减的单调栈的话&#xff0c;会发现只有单调栈里的元素是有用的。因为如果有 \(A[i]<A[j] \And i<j\)&#xff0c;那电梯就可以在带 \(j\) 上楼的时候顺便把 \(i\) 带上并不会影响结果。所以…

[Jinkey 原创]震惊!iOS 系统居然自带悬浮窗口调试工具

原文链接 : 震惊&#xff01;iOS 系统居然自带悬浮窗口调试工具 —— Jinkey 原创原文作者 : Jinkey1 背景 英文原文&#xff1a;http://ryanipete.com/blog/ios/swift/objective-c/uidebugginginformationoverlay/ 我写得这个并不是翻译而是用自己的理解重新表述这个功能&…

边分治讲解

前言&#xff1a; 边分治和点分治一样属于树分治的一部分&#xff0c;相比于点分治&#xff0c;边分治对于与度数相关的问题有着很大的优势&#xff0c;同时边分治也是解决树上最优化问题的一种重要的算法。 分治过程&#xff1a; 边分治的分治过程与点分治类似&#xff0c;同样…

Pycharm社区版配置Django

Pycharm开发版(收费)自带Django模板&#xff0c;社区版(免费)需要通过命令行创建Django项目。 通过pip安装Django&#xff1a;pip install django2.0.2(版本号)&#xff0c;可通过以下命令检查是否安装成功 在命令行下创建Django项目(项目存放在D:\PyCharm) 1.创建项目 进入D:\…

用Mesos分布式架构进行工作

引言&#xff1a;2010年&#xff0c;一个旨在解决扩容问题的项目诞生——Apache Mesos&#xff0c;它在某种程度上对CPU、内存、磁盘资源进行抽象&#xff0c;从而允许整个数据中心如同单台大服务器般运转。无需虚拟机和操作系统&#xff0c;Mesos创造了一个单独底层的集群为应…

不一样的视角,程序员世界里的环保

摘要&#xff1a; 我们身边有很多可以做的技术环保工作。比如说&#xff0c;在Linux下少用root用户&#xff0c;SQL的时候&#xff0c;delete前先select&#xff0c;这样&#xff0c;你就不会做出一些让你后悔的事。不会让你重头来过&#xff0c;从而至少不会浪费电能。写代码的…

oracle 会话 lock,相克军_Oracle体系_随堂笔记014-锁 latch,lock

1、Oracle锁类型锁的作用latch锁&#xff1a;chain&#xff0c;链LOCK锁排他锁(X)共享锁(S)2、行级锁&#xff1a;DML语句事务锁TX锁的结构事务锁的加锁和解锁过程只有排他锁不影响读(CR块)3、表级锁&#xff1a;TM行级排他锁(Row exclusive)RX锁当我们进行DML时&#xff0c;会…

TIOBE 10月编程语言排行榜 : GO 问鼎本年度语言 ?

距离2016年度编程语言的公布只剩3个月了&#xff0c;谁将夺得桂冠&#xff1f; 与去年同期相比&#xff0c;2016年只有Go语言和Groovy语言的增长率超过了1%。 需要注意的是&#xff0c;Groovy语言2015年以一个爆炸性增长的收尾&#xff0c;所以到2017年1月左右的增长速度可能不…

使用 ReSharper,输入即遵循 StyleCop 的代码格式化规范

StyleCop 可以帮助强制执行代码格式化规范&#xff0c;ReSharper 可以帮助你更高效地编写代码。把两者结合起来&#xff0c;你便能高效地编写符合团队强制格式化规范的代码来。 本文就介绍如何使用 ReSharper 来高效地遵循 StyleCop 的代码格式化规范。 本文内容 安装插件 Styl…

C# 控件双缓冲控制 ControlStyles 枚举详解

ControlStyles 枚举.NET Framework 4指定控件的样式和行为。 此枚举有一个 FlagsAttribute 特性&#xff0c;通过该特性可使其成员值按位组合。 命名空间&#xff1a; System.Windows.Forms程序集&#xff1a; System.Windows.Forms&#xff08;在 System.Windows.Forms.dll …

Java 9 将采用新的版本字符串格式

在现有的版本编码格式使用了两年之后&#xff0c;从Java 9开始&#xff0c;Java版本方案将根据业内软件版本编码的最佳实践进行修改。使用或解析Java版本字符串的应用程序开发人员要注意了&#xff0c;因为这种变化可以会影响他们的应用程序。 正如JEP 223所阐述的那样&#xf…

jQuery(爱前端)

一 jQuery 简介 官网&#xff1a;www.jquery.com 口号&#xff1a;写更少的代码&#xff0c;做更多的事情 jQuery 是一个快速、小型的、特性很多的JS库&#xff0c;它把很多事儿都变得简单。jQuery是免费的、开源的。 jQuery 是 DOM 编程领域的霸主&#xff0c;极大的简化了原生…