NSTimer、performSelector 函数没有被调用的原因
performSelector 指定的方法没有被调用
Invokes a method of the receiver on the current thread using the default mode after a delay.
根据苹果的文档,performSelector:withObject:afterDelay: 在指定时间之后,在当前线程 调用一个方法。如果这个线程在指定时间之后不存在了,自然也就不会调用这个方法了。
一个例子如下:
声明一个manager,里面有一个串行的队列,并在初始化方法中调用 performSelector:withObject:afterDelay: 方法。
- (instancetype)init
{
if (self = [super init])
{
_queue = dispatch_queue_create("test.tiger", DISPATCH_QUEUE_SERIAL);
[self performSelector:@selector(ontimeFunc) withObject:nil afterDelay:5];
}
return self;
}
调用的函数如下:
- (void)ontimeFunc
{
dispatch_async(self.queue, ^{
[self test];
});
}
- (void)test
{
NSLog(@"%@ called",NSStringFromClass([self class]));
[NSObject cancelPreviousPerformRequestsWithTarget:self];
//当前是非主线程。5s后,线程已经消失了,就不会被调用了。不能这么用
[self performSelector:@selector(ontimeFunc) withObject:nil afterDelay:5];
}
原本需要实现的目标是每 5s 调用 test函数一次。但是因为 performSelector:withObject:afterDelay:是在后台线程调用的,这个线程没有 RunLoop,所以 5s 后,线程已经不存在了,因此 test 方法一次都不会被调用。
这里需要修改的地方有两个:
- 在
init方法中,dispatch到主线程执行performSelector方法。 - 在
test方法中,也需要dispatch到主线程执行performSelector方法。
其实不一定需要到主线程中,只需要 5s 后,线程存在即可。
NSTimer 没有被触发
Timers work in conjunction with run loops
Apple 的文档中,第一句话就是定时器和 RunLoop 是联合工作的。定时器必须被加到 RunLoop 中才能被执行。
创建定时器有两种方法:
scheduledTimerWithTimeInterval:repeats:block:
创建一个定时器,并加到当前 RunLoop 的 default mode 中。timerWithTimeInterval:repeats:block:
只是创建一个定时器,需要手动加到 RunLoop 中。
因此如果使用第二种方法,对应的代码不会被延迟执行。
此外,如果在后台队列中创建定时器,可以 dispatch 到主线程中创建,因为后台队列对应的线程很可能会马上消失。
如果把定时器加入的 mode A,指定时间后,当前 RunLoop 处于 mode B,那么也不会被执行。比如把定时器加到 default mode 下,当 scrollview 滚动时,会处于 UITrackingMode,不会被触发。
关于 RunLoop 的知识,可以参考苹果文档及底部链接。
参考
NSTimer、performSelector 函数没有被调用的原因的更多相关文章
- C51函数的递归调用
前几天在写C51程序时用到了递归,简单程序如下: void WRITE_ADD(uchar addr,uchar wbyte) { START(); //先发送起始信号 WRITE_BYTE(0xa0 ...
- Linux Shell函数定义与调用
一.Shell函数定义格式 shell函数定义格式,各部分说明如下: [ function ]等中括号括起来部分----表示可选(即可有可无) your_function_name部分----为函数名 ...
- Javascript 自动执行函数(立即调用函数)
开头:各种原因总结一下javascript中的自动执行函数(立即调用函数)的一些方法,正文如下 在Javascript中,任何function在执行的时候都会创建一个执行上下文,因为function声 ...
- JavaScript 之有趣的函数(函数声明、调用、预解析、作用域)
前言:“函数是对象,函数名是指针.”,函数名仅仅是指向函数的指针,与其他包含函数指针的变量没有什么区别,话句话说,一个函数可能有多个名字. -1.函数声明,function+函数名称.调用方法:函数名 ...
- javascript、jQuery函数定义和调用方法
一.javascript 1.var aaa=function(){...} var 方式定义的函数,不能先调用函数,后声明,只能先声明函数,然后调用. 2.function aaa(){...} f ...
- php闭包实现函数的自调用,也是递归
php的闭包可能不常用,但是在某些场合之下还是可以考虑用php的闭包来实现某些功能的,比如递归,这里讲一下用php的闭包实现递归 //php闭包实现函数的自调用,也就是实现递归 function cl ...
- [Effective JavaScript 笔记]第17条:间接调用eval函数优于直接调用
eval函数不仅仅是一个函数.大多数函数只访问定义它们所在的作用域,而不能访问除此之外的作用域(词法作用域).eval函数具有访问调用它时的整个作用域的能力.编译器编写者首次设法优化js时,eval函 ...
- JavaScript函数参数与调用
函数调用: /* 1. 函数调用 */ ,,,); /* 2. 方法调用 */ this.CName = "全局"; var o = { CName:"o类", ...
- WebView中Js与Android本地函数的相互调用
介绍 随着Html5的普及,html在表现力上不一定比原生应用差,并且有很强的扩展兼容性,所以越来越多的应用是采用Html与Android原生混合开发模式实现. 既然要实现混合开发,那么Js与Andr ...
随机推荐
- SVN中检出 和 导出 的区别
SVN中检出 和 导出 的区别:检出得到的文件夹中,是受SVN客户端控制的,对其进行文件或文件夹的增删改操作都会被SVN客户端识别出来,对其可以进行update.commit操作.其中含有.svn隐藏 ...
- 2018.08.01 BZOJ4552: [Tjoi2016&Heoi2016]排序(二分+线段树)
传送门 线段树简单题. 二分答案+线段树排序. 实际上就是二分答案mid" role="presentation" style="position: relat ...
- Redis总结和提取常用的和重要的命令
一:Redis的结构和其数据类型(注redis默认端口号是6379) 1)Redis可以部署多套(多个进程不同端口或直接部署在不同主机),每个Redis都可以有多个db,通过select来选择,默认的 ...
- Object-C中 - self 和super 的含义
//super:父类 //self:自己 //自己理解 //以MobilePhone为例,父类为NSObject //在类方法 ...
- hdu 4998 矩阵表示旋转
http://acm.hdu.edu.cn/showproblem.php?pid=4998 http://blog.csdn.net/wcyoot/article/details/33310329 ...
- 理解ValueStack的基本机制 OGNL表达式
ValueStack基础:OGNL(Object Graphic Navigatino Language) OGNL是Struts2中使用的一种表达式语言. 它可以用于,在JSP页面,使用标签方便的访 ...
- ASP.NET MVC 中单独的JS文件中获取Controller中设定的值
1,在Controller中的Action 中将指定值写上. // // GET: /Home/ public ActionResult Index() ...
- 【转一篇出处不明的文章】 Windows多线程通信方式
多线程通信的方法主要有以下三种: 1.全局变量 进程中的线程间内存共享,这是比较常用的通信方式和交互方式.注:定义全局变量时最好使用volatile来定义,以防编译器对此变量进行优化. 2.Messa ...
- .net core使用NLog记录
首先使用Nugut安装NLog, NLog.Extensions.Logging,using NLog.Web,并且加上配置文件 ”nlog.config“,配置文件内容网上都可以百度的到.这是我自己 ...
- jQuery-Load方法
1.load() 介绍:load() 方法通过 AJAX 请求从服务器加载数据,并把返回的数据放置到指定的元素中 该方法是最简单的从服务器获取数据的方法.它几乎与 $.get(url, data, s ...