如题,这是最近在修改一个数据同步模块时发现的问题。整个数据同步的任务是在App启动后放在一个后台执行的线程中的,执行某个单条数据同步任务成功后,会使用

  1. [self performSelector:(nonnull SEL) withObject:(nullable id) afterDelay:(NSTimeInterval)];

来执行下一个单条数据同步任务。通过调试,发现在执行到这行代码的时候,并没有调用 SEL 的方法。在确定存在这个方法后,一直没有想到原因,于是就谷歌之。答案就是,performSelector withObject afterDelay 方法在子线程中,并不会调用SEL方法,而 performSelector withObject 方法会直接调用。原因在于一下两点:

1、afterDelay方式是使用当前线程的定时器在一定时间后调用SEL,NO AfterDelay方式是直接调用SEL。
2、子线程中默认是没有定时器的。

所以,针对问题的解决方法也有两种:

1、开启线程的定时器

  1. [[NSRunLoop currentRunLoop] run];

2、使用dispatch_after来执行定时任务

    1. - (void)functionToDelay:(SEL)function param:(nullable id)param afterDelay:(NSTimeInterval)delay {
    2. dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, delay*NSEC_PER_SEC);
    3. dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    4. if ([self respondsToSelector:function]) {
    5. #pragma clang diagnostic push
    6. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    7. [self performSelector:function withObject:param];
    8. #pragma clang diagnostic pop
    9. }
    10. });
    11. }

QQ技术交流群290551701  http://cxy.liuzhihengseo.com/556.html

performSelector withObject afterDelay 在子线程上调用不运行的更多相关文章

  1. 千万别在UI线程上调用Control.Invoke和Control.BeginInvoke,因为这些是依然阻塞UI线程的,造成界面的假死

    原文地址:https://www.cnblogs.com/wangchuang/archive/2013/02/20/2918858.html .c# Invoke和BeginInvoke 区别 Co ...

  2. 子线程里调用performSelector需要注意什么

    以下代码执行顺序是什么 ? - (void)action { NSLog(@"1"); dispatch_queue_t queue = dispatch_get_global_q ...

  3. performSelector:withObject:afterDelay: 精要概览(持续更新)

    - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay; - ...

  4. android kotlin 子线程中调用界面UI组件崩溃

    UI 只能在主线程内更新,子线程需要更新UI组件时可以这样: fun fuck(){ Executors.newSingleThreadExecutor().execute{ // url reque ...

  5. C# 多线程详解 Part.02(UI 线程和子线程的互动、ProgressBar 的异步调用)

           我们先来看一段运行时会抛出 InvalidOperationException 异常的代码段: private void btnThreadA_Click(object sender, ...

  6. Android ThreadUtil 线程公共类,判断是否在主线程/ 子线程执行 相关操作

    前言:通常,我们写的公共的模块给别人用,但是这个模块又必须在特定的线程中执行. 比如,一个加载网络图片的的方法,需要在子线程中执行. /** * 加载网络图片 */ private void load ...

  7. 关于Qt在子线程中使用QMessageBox的折衷方法

    Qt将所有GUI相关的处理都限制在主线程中,这么做有助于防止意想不到的访问冲突产生,但也限制了线程中某些简单的UI交互的实现,比如QMessageBox. 因为QMessageBox必须在主线程中打开 ...

  8. WPF 利用子线程弹出子窗体的研究

    一般来说子线程都是用来处理数据的,主窗体用来实现展现,但是有些时候我们希望子窗体实现等待效果,遮挡主窗体并使主窗体逻辑正常进行,这个业务需求虽然不多,但是正好我们用到了,于是我打算把研究成果写在这了. ...

  9. [C#参考]主线程和子线程之间的参数传递

    几个进程在大多数情况下要包含很多的子线程,那么他们之间免不了的要互相传递很多的参数,那么参数怎么传递的呢? 主线程向子线程传递参数的方法 第一种方法:Thraed类有一个带参数的委托类型的重载形式,这 ...

随机推荐

  1. ffmpeg 的一些学习网站

    http://blog.csdn.net/leixiaohua1020/article/category/1360795 雷霄骅(leixiaohua1020)的专栏 http://dranger.c ...

  2. IOS从背景图中取色

    ​1. [代码][其他]代码     void *bitmapData; //内存空间的指针,该内存空间的大小等于图像使用RGB通道所占用的字节数. static CGContextRef Creat ...

  3. CI 模型公用查询函数

    /** * 多字段条件查询数据 * @param array $val array("name" => $value).name为要操作的字段,value为要操作的值 * @ ...

  4. CI核心文件分析之基准测试类 (Benchmark.php)

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /** * CodeIgniter * * ...

  5. php函数的参数引用变量

    在php.ini中将allow_call_time_pass_reference的值改为'on'.

  6. Java丨时间判断谁前谁后

    直奔主题: String date_str1 = "2016-06-02 23:03:123"; String date_str2 = "2016-06-03 03:03 ...

  7. Python: PS 滤镜--素描

    本文用 Python 实现 PS 滤镜中的素描特效,具体的算法原理和效果可以参考之前的博客: http://blog.csdn.net/matrix_space/article/details/386 ...

  8. BZOJ_3786_星系探索_splay维护出栈入栈序

    BZOJ_3786_星系探索_splay维护出栈入栈序 Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为 ...

  9. [小记]Windows下配置环境变量和需不需要重启问题

    经常看到一些软件的安装说明上写着,修改Windows的环境变量,然后重新启动计算机.这让人不禁产生疑问,修改环境变量之后真的要重启吗? 其实只要理解了环境变量的原理就可以做出正确的判断.环境变量是一些 ...

  10. 性能测试之Jmeter学习(四)

    本节主要讲解:如何创建Web测试计划 如何创建一个简单的测试计划,用于测试web站点? 1.明确测试需求:我们会模拟5个并发用户,对Jakarta Web站点的网个页面进行访问,另外每个并发用户都会运 ...