iOS中的定时操作比较和原理简单分析

定时操作对于开发人员来说有着广泛的应用场景;对于iOS开发,实现定时操作的手法也有多种,这里我们简单的进行比较和分析。

1. NSTimer  简单易上手,最高级的api,调用也比较方便。(精度也最低)

但:NSTimer在不做任何额外设置的情况下只能在主线程使用,且会受到其他任务的干扰(主线程runloop执行其他任务,nstimer就不能及时触发);

可以设置NSRunLoopCommonModes来对其加以改善,这个时候主线程的UI操作已经不会阻塞它的触发了。

performselector after delay 可以认为是1的变种,精度和NSTimer相同。

2.使用 gcd的api, dispatch_after来进行定时操作。

该api虽然属于gcd的操作序列,但调用也比较方便,同时不受主线程UI操作的干扰,精度也尚可;不失为NSTimer的一个高级替代品。

dispatch_source_set_timer 是一个更复杂一些的定时api方法,提供了更多的参数和设置,可以提供相对dispatch_after来说更好的精度(推测
dispatch_after可能使用了默认的精度,误差在几十毫秒左右)。

3.要获得更好的精度,需要使用更底层的api实现,大概可以精确到毫秒级别。

首先你要搞一个更牛逼的实时线程:

#include <mach/mach.h>
#include <mach/mach_time.h>
#include <pthread.h>
 
void move_pthread_to_realtime_scheduling_class(pthread_t pthread)
{
    mach_timebase_info_data_t timebase_info;
    mach_timebase_info(&timebase_info);
 
    const uint64_t NANOS_PER_MSEC = 1000000ULL;
    double clock2abs = ((double)timebase_info.denom / (double)timebase_info.numer) * NANOS_PER_MSEC;
 
    thread_time_constraint_policy_data_t policy;
    policy.period      = 0;
    policy.computation = (uint32_t)(5 * clock2abs); // 5 ms of work
    policy.constraint  = (uint32_t)(10 * clock2abs);
    policy.preemptible = FALSE;
 
    int kr = thread_policy_set(pthread_mach_thread_np(pthread_self()),
                   THREAD_TIME_CONSTRAINT_POLICY,
                   (thread_policy_t)&policy,
                   THREAD_TIME_CONSTRAINT_POLICY_COUNT);
    if (kr != KERN_SUCCESS) {
        mach_error("thread_policy_set:", kr);
        exit(1);
    }
}

然后你需要相对应的定时api:

#include <mach/mach.h>
#include <mach/mach_time.h>
 
static const uint64_t NANOS_PER_USEC = 1000ULL;
static const uint64_t NANOS_PER_MILLISEC = 1000ULL * NANOS_PER_USEC;
static const uint64_t NANOS_PER_SEC = 1000ULL * NANOS_PER_MILLISEC;
 
static mach_timebase_info_data_t timebase_info;
 
static uint64_t abs_to_nanos(uint64_t abs) {
    return abs * timebase_info.numer  / timebase_info.denom;
}
 
static uint64_t nanos_to_abs(uint64_t nanos) {
    return nanos * timebase_info.denom / timebase_info.numer;
}
 
void example_mach_wait_until(int argc, const char * argv[])
{
    mach_timebase_info(&timebase_info);
    uint64_t time_to_wait = nanos_to_abs(10ULL * NANOS_PER_SEC);
    uint64_t now = mach_absolute_time();
    mach_wait_until(now + time_to_wait);
}

参考文档:https://developer.apple.com/library/content/technotes/tn2169/_index.html

时间: 2024-08-03 15:07:55

iOS中的定时操作比较和原理简单分析的相关文章

GHOST漏洞原理简单分析

继 ShellShock漏洞之后,Linux又爆出一重大漏洞.网上各种关于漏洞检查和修复的文章,但很难找到一篇讲述这个漏洞原理的.在阅读网上流传的测试代码后,写一下个人对这个漏洞的简单分析. 这应该是漏洞发布的网址,里面有最详细的解释,本人才疏学浅,只看了少部分,想深入了解的可以直接阅读,如本文有错误,请指正. http://www.openwall.com/lists/oss-security/2015/01/27/9 漏洞简介: GHOST是Linux glibc库上的一个安全漏洞,CVE编

.NET中的IO操作之文件流用法分析_实用技巧

本文实例讲述了.NET中的IO操作之文件流用法.分享给大家供大家参考.具体分析如下: 读操作 复制代码 代码如下: //1.创建文件流 FileStream fsRead =new FileStream("1.txt",FileMode.Open); //2.创建缓冲区,正常情况下,是不会直接等于文件大小的.这里只有读,所以就这么干了. byte[] bytes =new byte[fsRead.Length]; //3.开始读取, 返回值是读取到的长度. int r =fsRead.

ios中创建可以拖动的view原理和实现详解(含代码)

有时候我们会需要在界面上拖动view;uiview是继承于uiresponder的,所以可以响应触摸相关的事件. 重点是以下一组方法: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesEnded:(NSSet *)touches withEvent:(UI

DWR的Converter实现原理简单分析及应用

我们在应用 DWR 调用远程方法时涉及到 JS 与 JAVA 之间参数和返回值的数据转换,例如: JS 的 123 与 Java 的 int或 Integer.long 间的转换 JS 的 "2009-06-23" 与 Java 的 java.util.Date 之间的转换 JS 的 "[1,2,3]" 与 Java 的 int[] 间的转换 JS 的 "{id:123, name: 'Unmi'}" 与 Java 的 Class Person{

PHP文件上传原理简单分析

//表单上传只能使用multipart/form-data编码格式 $_FILES系统函数; $_FILES['myFile']['name']文件名称 $_FILES['myFile']['type']文件的类型,服务端进行限制 image/** image/x-png application/x-zip-compressed $_FILES['myFile']['size']上传文件大小 $_FILES['myFile']['tmp_name']上传服务后保存临时文件名 $_FILES['m

PHP文件上传原理简单分析_php技巧

//表单上传只能使用multipart/form-data编码格式 $_FILES系统函数; $_FILES['myFile']['name']文件名称 $_FILES['myFile']['type']文件的类型,服务端进行限制 image/** image/x-png application/x-zip-compressed $_FILES['myFile']['size']上传文件大小 $_FILES['myFile']['tmp_name']上传服务后保存临时文件名 $_FILES['m

ios-iOS中如何定时发送本地通知

问题描述 iOS中如何定时发送本地通知 iOS中为什么我设置十点定时提醒,虽然到十点会提醒,但是其余整点时间也会提醒 这是怎么回事?求解 解决方案 估计还是你的程序逻辑写的有问题 解决方案二: 参考:http://blog.csdn.net/tangaowen/article/details/18810829

在Visual Studio 2013/2015上使用C#开发Android/IOS安装包和操作步骤

原文:在Visual Studio 2013/2015上使用C#开发Android/IOS安装包和操作步骤 Xamarin 配置手册和离线包下载  http://pan.baidu.com/s/1eQ3qw8a 具体操作: 安装前提条件 1. 安装Visual Studio 2013,安装过程省略,我这里安装的windows10 + vs2013 with update 4. 2. 安装Java SDK,按照Next一步步安装,此处省略,如下图: 3. 安装Android SDK:因为在线安装的

【iOS7的一些总结】11、iOS中的事件

1.原理       在应用程序成功启动后,应用程序就开始由外部事件进行驱动.应用程序不断获取事件,并作出响应并更新用户界面,然后等待下一个事件.这对事件进行循环响应的整个机制,称为主要事件循环,由一个全局应用程序对象(一个UIApplication实例)进行管理.       在事件循环中最重要的事件之一就是用户与设备的交互操作.在iOS设备中,用户对设备的操作可以通过多种方式,如点击屏幕或者晃动设备等.iOS操作系统会解析这些操作,并将响应通知应用做出相应.对这些操作进行更加自然和直观的相应