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 ...
随机推荐
- async 和 await
win8 app开发中使用async,await可以更方便地进行异步开发. async,await的使用可参考代码:Async Sample: Example from "Asynchron ...
- 557. Reverse Words in a String III
static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...
- 2018.09.19 atcoder Snuke's Coloring(思维题)
传送门 谁能想到这道题会写这么久. 本来是一道很sb的题啊. 就是每次选一个点只会影响到周围的九个方格,随便1e9进制就可以hash了,但是我非要作死用stl写. 结果由于技术不够高超,一直调不出来. ...
- 2018.07.12 atcoder Choosing Points(数学分析好题)
传送门 一句话题意:给出n,d1,d2" role="presentation" style="position: relative;">n,d ...
- Spring MVC之@RequestMapping 传递数组
1.前台: var param = {titles:['col1','col2','col3']}; $.ajax({url:url, type:"post", data:para ...
- Java带图片预览功能的图片上传兼容火狐ie
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Spring 获取资源文件路径
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; s ...
- ubuntu16.4中开启vncserver进行远程桌面
使用x11vnc作为vncserver端 1 安装x11vnc $ sudo apt-get update $ sudo apt-get install x11vnc 2 生成密码 $ x11vnc ...
- ScrollView嵌套listview ,滚动问题。设置listview不滚动
对于ListView内部的ListView,一般用来展示少量的列表数据. 内部的ListView的高度看起来是一个固定值且无法滑动,这个就比较蛋疼了.. 提供两种解决方案,方案的核心都是重新设置内部L ...
- 来回最短路POJ3268
这个题得主要考点在于给你的图是去了再回来得有向图,如何模块化解决呢就是转变图的方向,我们根据初始得放心求出每个点到x得最短路,然后转变所有路得方向再求出所有点到x得最短路,最后一相加就是最后的来回了~ ...