ios多线程操作(七)—— GCD延迟操作与一次性代码
来源:互联网 发布:怎么认识外国妹子软件 编辑:程序博客网 时间:2024/05/22 15:51
使用GCD函数可以进行延时操作,该函数为
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- });
现在我们来分解一下参数
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds *NSEC_PER_SEC)) :
NSEC_PER_SEC在头文件中的定义如下:
#define NSEC_PER_SEC 1000000000ull /* nanoseconds per second */
该参数表示从现在开始经过多少纳秒
dispatch_get_main_queue():表示主队列
^{
}:表示一个block任务。
我们可以来测试一下经过多少纳秒之后,由主队列调度任务是异步执行还是同步执行,代码如下:
- // when 时间 从现在开始经过多少纳秒
- dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));
- void (^task)() = ^ {
- // 延迟操作执行的代码
- NSLog(@"%@", [NSThread currentThread]);
- };
- // 经过多少纳秒,由主队列调度任务异步执行
- dispatch_after(when, dispatch_get_main_queue(), task);
- // 先执行就是异步,后执行就是同步
- NSLog(@"come here");
执行结果如下:
由此可见主队列中调度任务是异步执行的
再将执行队列改为全局队列和串行队列,得到的结果完全是一样的,由此可知该函数执行的是异步操作。
GCD中有个函数能够保证某段代码在程序运行过程中只被执行1次!该函数如下:
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- })
dispatch_once_t在头文件中得定义如下:
typedef long dispatch_once_t;
由此可知该类型是个long类型。当onceToken等于0时就会执行block代码。dispatch_once是线程安全的,只要涉及到线程安全就会涉及到锁,dispatch_once内部也有一把锁,性能比互斥锁高!
利用该函数我们可以来写一个单例模式
单例模式可以保证在程序运行过程,一个类只有一个实例且该实例易于供外界访问,从而方便控制实例个数,并节约系统资源,当应用程序需要共享一份资源时就可以用单例模式来实现。单例模式分ARC与MRC两种情况,我们可以用宏判断是否为ARC环境
- #if __has_feature(objc_arc)
- // ARC
- #else
- // MRC
- #endif
ARC环境下简单地单例模式:
- @implementation SoundTools
- // 定义一个静态成员,保存唯一的实例
- static id instance;
- // 保证对象只被分配一次内存空间,通过dispatch_once能够保证单例的分配和初始化是线程安全的
- + (instancetype)allocWithZone:(struct _NSZone *)zone {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- instance = [super allocWithZone:zone];
- });
- return instance;
- }
- // 保证对象只被初始化一次
- + (instancetype)sharedSoundTools {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- instance = [[self alloc] init];
- });
- return instance;
- }
- - (id)copyWithZone:(NSZone *)zone {
- return instance;
- }
- @end
- 测试代码如下:
- - (void)viewDidLoad {
- [super viewDidLoad];
- SoundTools *s1 = [SoundTools sharedSoundTools];
- NSLog(@"%p", s1);
- }
- - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
- SoundTools *s2 = [SoundTools sharedSoundTools];
- NSLog(@"%p", s2);
- }
两个方法打印出来的地址完全一样!
在MRC环境下有如下代码:
- // 定义一个静态成员,保存唯一的实例
- static id instance;
- // 保证对象只被分配一次内存空间,通过dispatch_once能够保证单例的分配和初始化是线程安全的
- + (instancetype)allocWithZone:(struct _NSZone *)zone {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- instance = [super allocWithZone:zone];
- });
- return instance;
- }
- // 保证对象只被初始化一次
- + (instancetype)sharedSoundTools {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- instance = [[self alloc] init];
- });
- return instance;
- }
- - (id)copyWithZone:(NSZone *)zone {
- return instance;
- }
- #pragma mark - MRC内存管理方法
- /**
- 因为单例的对象是保存在静态区的,因此需要重写 内存管理方法,取消默认的引用计数操作!
- */
- // 默认会将引用计数-1
- - (oneway void)release {
- // 什么也不做,跟highlight类似
- }
- // 默认引用计数+1,同时返回一个对象
- - (instancetype)retain {
- return instance;
- }
- // 默认添加自动释放标记,延迟释放!
- - (instancetype)autorelease {
- return instance;
- }
- // 返回有多少个对象对当前对象引用的数值
- - (NSUInteger)retainCount {
- // 出处:limits.h 会根据CPU的架构自行调整整数的长度
- return ULONG_MAX;
- }
0 0
- ios多线程操作(七)—— GCD延迟操作与一次性代码
- ios多线程操作(七)—— GCD延迟操作与一次性代码
- IOS多线程操作之一次性代码
- GCD高级功能(一次性执行,调度组,延迟操作)
- ios多线程操作(四)—— GCD核心概念
- ios多线程操作(八)—— GCD调度组
- ios多线程操作(四)—— GCD核心概念
- ios多线程操作(八)—— GCD调度组
- ios多线程操作(五)—— GCD串行队列与并发队列
- ios多线程操作(六)—— GCD全局队列与主队列
- ios多线程操作(五)—— GCD串行队列与并发队列
- ios多线程操作(六)—— GCD全局队列与主队列
- ios多线程操作(六)—— GCD全局队列与主队列
- iOS 多线程之延迟操作
- IOS开发(63)之GCD执行延迟操作
- GCD之——延迟执行、调度组、以及一次性执行代码
- iOS 开发 多线程详解之GCD应用延迟操作,单例设计模式,调度组
- GCD常见的几种用法-- 延迟\一次性代码\多线程同时遍历\栈栏
- Code Forces 645A Amity Assessment
- Android中自定义checkbox样式
- leetcode 65. Valid Number
- HDU 5421 Victor and String
- linux 用户环境变量介绍
- ios多线程操作(七)—— GCD延迟操作与一次性代码
- 五步搞定Android开发环境部署——非常详细的Android开发环境搭建教程
- ios多线程操作(八)—— GCD调度组
- 小明传球
- 二进制原码,反码以及补码实战
- ios多线程操作(九)—— 用NSOperation代替GCD
- 虚拟机对象探秘
- HDU 2071
- 5.3 一致性