performSelector: 与 dispatch_time 异同


iOS中timer相关的延时调用,常见的有NSObject中的performSelector:withObject:afterDelay:这个方法在调用的时候会设置当前runloop中timer,还有一种延时,直接使用NSTimer来配置任务。

1.这两种方式都一个共同的前提,就是当前线程里面需要有一个运行的runloop并且这个runloop里面有一个timer。

我们知道:只有主线程会在创建的时候默认自动运行一个runloop,并且有timer,普通的子线程是没有这些的。这样就带来一个问题了,有些时候我们并不确定我们的模块是不是会异步调用到,而我们在写这样的延时调用的时候一般都不会去检查运行时的环境,这样在子线程中被调用的时候,我们的代码中的延时调用的代码就会一直等待timer的调度,但是实际上在子线程中又没有这样的timer,这样我们的代码就永远不会被调到。

2.下面的代码展示了performSelector和dispatch_time的不同

在有多线程操作的环境中,这样performSelector的延时调用,其实是缺乏安全性的。我们可以用另一套方案来解决这个问题,就是使用GCD中的dispatch_after来实现单次的延时调用

/*
 testDispatch_after 延时添加到队列
 */
-(void) testDispatch_after
{
    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3*NSEC_PER_SEC);
    dispatch_after(time, dispatch_get_main_queue(), ^
{
        NSLog(@"3秒后添加到队列");
});
}
-(void) testDelay
{
    NSLog(@"3秒后testDelay被执行");
}
/*
 dispatch_barrier_async 栅栏的作用
 */
-(void) testDispatch_Barrier{
    //dispatch_queue_t gcd = dispatch_queue_create("这是序列队列", NULL);
    dispatch_queue_t gcd = dispatch_queue_create("这是并发队列", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(gcd, ^
{
        NSLog(@"b0");
        //这个selector不会执行
        [self performSelector:@selector(testDelay) withObject:nil afterDelay:3];
        //代码会执行
        //[self testDispatch_after];
    });
    dispatch_release(gcd);
}

时间: 2024-08-30 01:53:18

performSelector: 与 dispatch_time 异同的相关文章

iOS多线程中performSelector: 和dispatch_time的不同

iOS中timer相关的延时调用,常见的有NSObject中的performSelector:withObject:afterDelay:这个方法在调用的时候会设置当前runloop中timer,还有一种延时,直接使用NSTimer来配置任务. 这两种方式都一个共同的前提,就是当前线程里面需要有一个运行的runloop并且这个runloop里面有一个timer. 我们知道:只有主线程会在创建的时候默认自动运行一个runloop,并且有timer,普通的子线程是没有这些的.这样就带来一个问题了,有

iOS NSRunLoop那些事

iOS中timer相关的延时调用,常见的有NSObject中的performSelector:withObject:afterDelay:这个方法在调用的时候会设置当前runloop中timer,还有一种延时,直接使用NSTimer来配置任务. 这两种方式都一个共同的前提,就是当前线程里面需要有一个运行的runloop并且这个runloop里面有一个timer. 我们知道:只有主线程会在创建的时候默认自动运行一个runloop,并且有timer,普通的子线程是没有这些的.这样就带来一个问题了,有

初探swift语言的学习笔记十一(performSelector)

作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/35842441 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号fengsh998来支持我,谢谢! 在OC中使用好好的performSelector,但不知为什么在swift有意的被拿掉了.更有甚者连IMP, objc_msgSend也不能用了.虽然想不通为什么,但应该有他的道理.就不纠结了. 大家可能在OC中使用得更多的就是延时处理,及后台处

iOS 消息处理之performSelector

////  RootViewController.h//  DSCategories////  Created by dasheng on 15/12/17.//  Copyright ? 2015年 dasheng. All rights reserved.// #import <UIKit/UIKit.h> @interface RootViewController : UITableViewController @end ////  RootViewController.m//  DSC

performSelector withObject afterDelay 在子线程上调用不运行

如题,这是最近在修改一个数据同步模块时发现的问题.整个数据同步的任务是在App启动后放在一个后台执行的线程中的,执行某个单条数据同步任务成功后,会使用 Objective-c代码   [self performSelector:(nonnull SEL) withObject:(nullable id) afterDelay:(NSTimeInterval)]; 来执行下一个单条数据同步任务.通过调试,发现在执行到这行代码的时候,并没有调用 SEL 的方法.在确定存在这个方法后,一直没有想到原因

架构(三层架构)、框架(MVC)、设计模式三者异同点

对于没有排序功能的集合来说,都可以使用java.util.Collections.sort()方法进行排序,它除了集合对象以外,还需要提供一个比较器.如果列表中的元素全部都是相同的类型,并且这个类实现了Comparable接口,就可以简单的调用Collections.sort()方法,如果这个类没有实现comparable接口,那么可以创建一个比较器传递一个Comparator实例作为Sort()的第二个参数进行排序,另外,如果不想使用默认的分类顺序进行排序,同样也可以传递一个Comparato

关于commonjs,AMD,CMD之间的异同

1.简介 随着前端业务复杂度的增加,模块化成为一个大的趋势.而在ES6还未被浏览器所支持的情况下,commonjs作为ES6中标准模块加载方案,在客服端中的支持情况并不好,现在在客服端中有2中模块化的解决方案,CMD和AMD,他们的代表分别为seajs和requirejs.这篇文章主要介绍我对commonjs.AMD以及CMD的理解. 2.commonJS commonjs的目标是制定一个js模块化的标准,它的目标制定一个可以同时在客服端和服务端运行的模块.这些模块拥有自己独立的作用域,也可以向

2分钟读懂Hadoop和Spark的异同

谈到大数据框架,现在最火的就是Hadoop和Spark,但我们往往对它们的理解只是提留在字面上,并没有对它们进行深入的思考,倒底现在业界都在使用哪种技术?二者间究竟有哪些异同?它们各自解决了哪些问题?下面不妨跟我一块看下它们究竟有什么异同. 解决问题的层面不一样 首先,Hadoop和Apache Spark两者都是大数据框架,但是各自存在的目的不尽相同.Hadoop实质上更多是一个分布式数据基础设施: 它将巨大的数据集分派到一个由普通计算机组成的集群中的多个节点进行存储,意味着您不需要购买和维护

C#扫盲之:==/Equals /ReferenceEquals 异同的总结,相等性你真的知道吗?

1.前言 == Equals ReferenceEquals 三个相等性测试,是.NET提供给程序员使用的三个方法,他们之间有什么联系和区别,你真的仔细研究过?虽然之前也多多少少知道一点,但是有时候又难免混淆他们之间的概念和所适用的场合,决定做一个总结系统的描述这三个宝宝 2.值类型比较和引用类型比较 在编程中实际上我们只需要这两种比较,c#中类型也就这两种 (1)值类型的比较:一般我们就是判断两个值类型实例的各自包含的值是否相等 (2)引用类型的比较:由于引用类型在内存中的分布有两部分,一个是