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 方法一次都不会被调用。

这里需要修改的地方有两个:

  1. init 方法中,dispatch到主线程执行 performSelector 方法。
  2. 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 函数没有被调用的原因的更多相关文章

  1. C51函数的递归调用

    前几天在写C51程序时用到了递归,简单程序如下: void WRITE_ADD(uchar addr,uchar wbyte) { START(); //先发送起始信号 WRITE_BYTE(0xa0 ...

  2. Linux Shell函数定义与调用

    一.Shell函数定义格式 shell函数定义格式,各部分说明如下: [ function ]等中括号括起来部分----表示可选(即可有可无) your_function_name部分----为函数名 ...

  3. Javascript 自动执行函数(立即调用函数)

    开头:各种原因总结一下javascript中的自动执行函数(立即调用函数)的一些方法,正文如下 在Javascript中,任何function在执行的时候都会创建一个执行上下文,因为function声 ...

  4. JavaScript 之有趣的函数(函数声明、调用、预解析、作用域)

    前言:“函数是对象,函数名是指针.”,函数名仅仅是指向函数的指针,与其他包含函数指针的变量没有什么区别,话句话说,一个函数可能有多个名字. -1.函数声明,function+函数名称.调用方法:函数名 ...

  5. javascript、jQuery函数定义和调用方法

    一.javascript 1.var aaa=function(){...} var 方式定义的函数,不能先调用函数,后声明,只能先声明函数,然后调用. 2.function aaa(){...} f ...

  6. php闭包实现函数的自调用,也是递归

    php的闭包可能不常用,但是在某些场合之下还是可以考虑用php的闭包来实现某些功能的,比如递归,这里讲一下用php的闭包实现递归 //php闭包实现函数的自调用,也就是实现递归 function cl ...

  7. [Effective JavaScript 笔记]第17条:间接调用eval函数优于直接调用

    eval函数不仅仅是一个函数.大多数函数只访问定义它们所在的作用域,而不能访问除此之外的作用域(词法作用域).eval函数具有访问调用它时的整个作用域的能力.编译器编写者首次设法优化js时,eval函 ...

  8. JavaScript函数参数与调用

    函数调用: /* 1. 函数调用 */ ,,,); /* 2. 方法调用 */ this.CName = "全局"; var o = { CName:"o类", ...

  9. WebView中Js与Android本地函数的相互调用

    介绍 随着Html5的普及,html在表现力上不一定比原生应用差,并且有很强的扩展兼容性,所以越来越多的应用是采用Html与Android原生混合开发模式实现. 既然要实现混合开发,那么Js与Andr ...

随机推荐

  1. seo工具

    http://tool.seowhy.com/ 一.关键词查词类工具:可以查询出更多目标客户可能搜索的词语 1.百度指数:http://index.baidu.com/ 这个工具是使用人数最多的 2. ...

  2. iOS沙盒机制介绍

    一.沙盒机制 沙盒的概念:沙盒是每一个iOS应用程序都会自动创建的一个文件系统目录(文件夹),而且沙盒还具有独立.封闭.安全的特点. 沙盒机制 iOS中的沙盒不仅仅是一个文件目录,TA其实更是一种安全 ...

  3. 2018.08.27 lucky(模拟)

    描述 Ly 喜欢幸运数字,众所周知,幸运数字就是数字位上只有 4 和 7 的数字. 但是本题的幸运序列和幸运数字完全没关系,就是一个非常非常普通的序列. 哈哈,是 不是感觉被耍了,没错,你就是被耍了. ...

  4. cgo -rpath指定动态库路径

    // #cgo CFLAGS: -Wall // #cgo LDFLAGS: -Wl,-rpath="/home/liuliang/ffmpeg-build/lib" // #cg ...

  5. gj9 迭代器和生成器

    9.1 python的迭代协议 list内部实现了__iter__()协议(魔法函数),是可迭代对象,但还不是迭代器(迭代器需要实现__next__协议) 生成器实现了__iter__(),__nex ...

  6. php读取用友u8采购入库单列表及详细

    <?php class erpData { protected static $erp; public function __construct() { $dbhost ="192.1 ...

  7. QDesktopWidget

    在Qt中提供了QDesktopWidget类,提供屏幕的有关信息. 可以这么作: QDesktopWidget *d=QApplication::desktop(); int width=d-> ...

  8. 201709018工作日记--RecyclerView的使用(点击,瀑布流的实现)

    参考相关博客: http://www.jianshu.com/p/55e3f1b6701f  刘望舒 http://www.jianshu.com/p/4fc6164e4709 王三的猫阿德 http ...

  9. MySQL性能调优与架构设计——第13章 可扩展性设计之 MySQL Replication

    第13章 可扩展性设计之 MySQL Replication 前言: MySQL Replication 是 MySQL 非常有特色的一个功能,他能够将一个 MySQL Server 的 Instan ...

  10. (KMP 最大表示最小表示)String Problem -- hdu-- 3374

    http://acm.hdu.edu.cn/showproblem.php?pid=3374 String Problem Time Limit: 2000/1000 MS (Java/Others) ...