Objective-C的NSTimer学习笔记

Objective-C的NSTimer学习笔记NSTimer – 计时器 NSTimer派生自NSObject,是一种计时器,在经过一定的时间间隔后触发,向目标对象发送指定的消息。 计时器(NSTimer)与运行循环(RunLoop)一起工作。运

NSTimer – 计时器

NSTimer派生自NSObject,是一种计时器,在经过一定的时间间隔后触发,向目标对象发送指定的消息。

计时器(NSTimer)与运行循环(RunLoop)一起工作。运行循环维护对其计时器的强引用,因此在将计时器添加到运行循环后,不必自己维护对计时器的强引用

计时器不是实时机制。如果计时器的触发时间发生在长运行循环调用期间,或者当运行循环处于不监视计时器的模式时,计时器在下次运行循环检查计时器之前不会触发,因此计时器触发的实际时间可能要晚得多。

NSTimer创建计时器函数
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;

函数描述使用指定的调用对象初始化计时器对象。必须使用addTimer:forMode:方法将初始化的计时器添加到运行循环中(如果计时器配置为重复,则一次计时结束无需将计时器重新添加到运行循环中)。然后,在ti过去之后,计时器将触发,由调用对象执行其调用。

参数 :

ti :计时器触发之间的秒数。如果ti小于或等于0.0,此方法将选择非负值0.1毫秒。

invocation :计时器触发时要使用的调用对象。计时器指示调用对象维护对其参数的强引用。

repeats :是否重复,如果是YES,计时器将重复重新安排自己,直到失效。如果NO,计时器将在其触发后失效。

返回值 :一个新的根据指定的参数进行配置的NSTimer对象。

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

函数描述使用指定的对象和选择器初始化计时器对象。必须使用addTimer:forMode:方法将新计时器添加到运行循环中(如果计时器配置为重复,则一次计时结束无需将计时器重新添加到运行循环中)。然后,经过ti秒后,计时器启动,向目标发送selector消息。

参数 :

ti :计时器触发之间的秒数。如果ti小于或等于0.0,此方法将选择非负值0.1毫秒。

aTarget :当计时器触发时,选择器指定要向其发送消息的对象。计时器维持对目标的强引用,直到它(计时器)失效。

aSelector :计时器触发时要发送给目标的消息。

repeats :是否重复,如果是YES,计时器将重复重新安排自己,直到失效。如果NO,计时器将在其触发后失效。

返回值 :一个新的根据指定的参数进行配置的NSTimer对象。

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (NS_SWIFT_SENDABLE ^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

函数描述使用指定的时间间隔和块初始化计时器对象。必须使用addTimer:forMode:将新计时器添加到运行循环中(如果计时器配置为重复,则一次计时结束无需将计时器重新添加到运行循环中)。然后,在间隔秒后,计时器启动,执行块。

参数 :

interval :计时器启动之间的秒数。如果间隔小于或等于0.0,此方法将选择非负值0.1毫秒。

repeats :是否重复,如果是YES,计时器将重复重新安排自己,直到失效。如果NO,计时器将在其触发后失效。

block :计时器启动时要执行的块。该块采用单个NSTimer参数,并且没有返回值。

返回值 :一个新的根据指定的参数进行配置的NSTimer对象。

- (instancetype)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (NS_SWIFT_SENDABLE ^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

函数描述使用指定日期与时间间隔以及一个块初始化计时器对象。 必须使用addTimer:forMode:方法将新计时器添加到运行循环中(如果计时器配置为重复,则一次计时结束无需将计时器重新添加到运行循环中)。在指定日期到达后计时器触发,之后每间隔interval秒,计时器触发,执行block。

参数 :

date :计时器应首次启动的时间。

interval :计时器启动之间的秒数。如果间隔小于或等于0.0,此方法将选择非负值0.1毫秒。

repeats :是否重复,如果是YES,计时器将重复重新安排自己,直到失效。如果NO,计时器将在其触发后失效。

block :计时器启动时要执行的块。该块采用单个NSTimer参数,并且没有返回值。

返回值 :一个新的根据指定的参数进行配置的NSTimer对象。

- (instancetype)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)ti target:(id)t selector:(SEL)s userInfo:(nullable id)ui repeats:(BOOL)rep NS_DESIGNATED_INITIALIZER;

函数描述使用指定的对象和选择器初始化计时器。必须使用addTimer:forMode:方法将新计时器添加到运行循环中(如果计时器配置为重复,则一次计时结束无需将计时器重新添加到运行循环中)。在指定日期到达后计时器触发,之后每间隔interval秒,计时器触发,向目标发送aSelector消息。

参数 :

date :计时器应首次启动的时间。

ti :计时器启动之间的秒数。如果间隔小于或等于0.0,此方法将选择非负值0.1毫秒。

t :当计时器触发时,选择器指定要向其发送消息的对象。计时器维持对目标的强引用,直到它(计时器)失效。

s :计时器触发时要发送给目标的消息。

ui : 计时器的用户信息。计时器维持对这个对象的强引用,直到它(计时器)失效。这个参数可以是nil。

rep : 是否重复,如果是YES,计时器将重复重新安排自己,直到失效。如果NO,计时器将在其触发后失效。


例如:需要添加到运行循环中的计时器 \color{red}{例如:需要添加到运行循环中的计时器}

- (void)viewDidLoad {
    [super viewDidLoad];
    //获取方法签名对象
    NSMethodSignature *signature = [self methodSignatureForSelector:NSSelectorFromString(@"timerAction")];
    //获取调用对象,设置调用对象调用者与调用消息
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    invocation.target = self;
    invocation.selector = NSSelectorFromString(@"timerAction");
    //计时器加入运行循环
    [[NSRunLoop mainRunLoop] addTimer:[NSTimer timerWithTimeInterval:1.0 invocation:invocation repeats:YES] forMode:NSRunLoopCommonModes];
}

///计时器调用函数
- (void)timerAction {
    NSLog(@"计时器工作中");
}

不加入运行循环,则只会打印一次,加入运行循环后,打印如下 :

截屏2023-03-27 11.24.53.png

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;

函数描述创建计时器并以默认模式在当前运行循环上调度它。在ti秒过去后,计时器触发,由调用对象执行其调用。

参数 :

ti :计时器启动之间的秒数。如果ti小于或等于0.0,此方法将选择非负值0.1毫秒。

invocation :计时器触发时要使用的调用对象。计时器指示调用对象维护对其参数的强引用。

repeats :是否重复,如果是YES,计时器将重复重新安排自己,直到失效。如果NO,计时器将在其触发后失效。

返回值 : 根据指定参数配置的新NSTimer对象。

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

函数描述创建计时器并以默认模式在当前运行循环上调度它。在ti秒过去后,计时器触发,发送消息选择器到目标。

参数 :

ti :计时器启动之间的秒数。如果ti小于或等于0.0,此方法将选择非负值0.1毫秒。

aTarget :当计时器触发时,选择器指定要向其发送消息的对象。计时器维持对目标的强引用,直到它(计时器)失效。

aSelector :计时器触发时要发送给目标的消息。

userInfo : 计时器的用户信息。计时器维持对这个对象的强引用,直到它(计时器)失效。这个参数可以是nil。

repeats : 是否重复,如果是YES,计时器将重复重新安排自己,直到失效。如果NO,计时器将在其触发后失效。

返回值 : 根据指定参数配置的新NSTimer对象。

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (NS_SWIFT_SENDABLE ^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

函数描述创建一个计时器,并在默认模式下在当前运行循环中对其进行调度。在间隔秒后,计时器启动,执行块。

参数 :

interval : 计时器启动之间的秒数。如果间隔小于或等于0.0,此方法将选择非负值0.1毫秒。

repeats :是否重复,如果是YES,计时器将重复重新安排自己,直到失效。如果NO,计时器将在其触发后失效。

block :计时器启动时要执行的块。该块采用单个NSTimer参数,并且没有返回值。

返回值 :一个新的根据指定的参数进行配置的NSTimer对象。


例如:以默认模式在当前运行循环上执行计时器 \color{red}{例如:以默认模式在当前运行循环上执行计时器 }

- (void)viewDidLoad {
    [super viewDidLoad];
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
}

///计时器调用函数
- (void)timerAction {
    NSLog(@"计时器工作中");
}

打印如下 :

截屏2023-03-27 15.10.33.png

NSTimer触发与销毁计时器函数
- (void)fire;

函数描述:使计时器的消息被发送到它的目标。可以使用此方法来触发重复计时器而不中断其常规触发计划。如果计时器是非重复的,它在触发后会自动失效,即使它的预定触发日期还没有到达。

- (void)invalidate;

函数描述停止触发的计时器,并请求将其从运行循环中删除。这个方法是从NSRunLoop对象中删除计时器的唯一方法。NSRunLoop对象会在invalidate方法返回之前或之后的某个时间点删除它对计时器的强引用。如果配置了target和userInfo对象,计时器也会删除对这些对象的强引用。

常用属性
@property (copy) NSDate *fireDate;

属性描述计时器触发的日期。如果计时器已经失效,则为计时器触发的最后日期。可以设置此属性以调整重复计时器(repeats为YES)的触发时间。尽管重置计时器的下一次触发时间是一个相对昂贵的操作,但在某些情况下它可能更有效。例如,可以在未来想要以不规则的时间间隔多次重复某个操作的情况下使用它。调整单个计时器的触发时间比创建多个计时器对象,在一个运行循环中调度每个对象,然后销毁它们所产生的开销要小。

对于已经失效的计时器(包括已经触发的非重复计时器),不应该更改其触发日期。可以更改尚未触发的非重复计时器的触发日期,但应该始终从计时器所连接的线程进行更改。使用valid属性可以验证计时器是否有效。

@property (readonly) NSTimeInterval timeInterval;

属性描述计时器的时间间隔,以秒为单位。如果计时器不重复,即使设置了时间间隔,也会返回0。

@property NSTimeInterval tolerance API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0));

属性描述计时器到达预定触发日期,触发时可以应用的额外时间容差。默认值为0,这意味着没有应用额外的容差。为计时器设置容差可以使其在预定触发日期到达后,偏移计时器触发。计时器可以在预定触发日期与额外时间容差加上预定触发日期之间的任何时间触发。允许系统在计时器触发时具有灵活性,可以提高系统优化的能力,以提高功耗节省和响应能力。

@property (readonly, getter=isValid) BOOL valid;

属性描述:一个布尔值,用于指示计时器当前是否有效。如果计时器仍然能够触发,则为YES;如果计时器已经失效并且不再能够触发,那么为NO。

@property (nullable, readonly, retain) id userInfo;

属性描述计时器的userInfo对象。计时器无效后,不要访问此属性。使用valid属性验证计时器是否有效。

NSRunLoop – 运行循环

一个管理输入源(手势、Selector等)的对象,Runloop即运行循环,是iOS中的消息处理机制,其主要作用是控制NSRunLoop里面线程的执行和休眠,当某个事件执行完成后,不退出其线程而进入休眠状态,当再次检测到事件时。唤醒休眠的线程继续处理事件。RunLoop可以保持程序的持续运行,并节省CPU资源,提高程序性能。

NSRunLoop是对CFRunLoopRef的一层封装, 是Objective-C的语法的框架。CFRunLoopRef是基于C语言的开源框架。

从NSRunLoop的角度来看,NSTimer对象并不是输入源,它们是一种特殊的类型,当它们被触发时,不会导致运行循环返回。

NSRunLoop类通常不是线程安全的,只能在当前线程的上下文中调用它的方法。

NSRunLoop 处理事件流程:

26031781-ad7d1505ba7b3e59.png

NSRunLoop常用属性
@property (class, readonly, strong) NSRunLoop *currentRunLoop

属性描述类属性,返回当前线程的运行循环(NSRunLoop对象)。如果线程还不存在运行循环,则会创建并返回一个运行循环。

@property (class, readonly, strong) NSRunLoop *mainRunLoop API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));

属性描述类属性,返回主线程的运行循环(NSRunLoop对象)

@property (nullable, readonly, copy) NSRunLoopMode currentMode;

属性描述:调用方的当前输入模式。这个方法仅在调用方运行时返回当前的输入模式,否则它返回nil。

  • Runloop模式:
1.NSDefaultRunLoopMode:默认状态(空闲状态),比如点击按钮都是这个状态
2.UITrackingRunLoopMode:滑动时的Mode。比如滑动UIScrollView时。
3.UIInitializationRunLoopMode:私有的,APP启动时。就是从iphone桌面点击APP的图标进入APP到第一个界面展示之前,在第一个界面显示出来后,UIInitializationRunLoopMode就被切换成了NSDefaultRunLoopMode4.NSRunLoopCommonModes:它是NSDefaultRunLoopModeUITrackingRunLoopMode的集合。结构类似于一个数组。在这个mode下执行其实就是两个mode都能执行而已。
NSRunLoop常用函数
- (CFRunLoopRef)getCFRunLoop CF_RETURNS_NOT_RETAINED;

函数描述返回调用方的基础CFRunLoop对象。可以使用返回的运行循环来使用Core Foundation函数调用配置当前运行循环。例如可以使用此函数来设置运行循环观察者。

返回值 :调用方的基础CFRunLoop对象。

- (void)addTimer:(NSTimer *)timer forMode:(NSRunLoopMode)mode;

函数描述使用给定的输入模式注册给定的计时器。可以将计时器添加到多种输入模式中。在指定模式下运行时,调用方会使计时器在其计划的启动日期当天或之后启动。触发后,计时器调用其关联的处理程序例程,该例程是指定对象上的选择器。调用方保留计时器。要从安装计时器的所有运行循环模式中删除计时器,需要向计时器发送invalidate消息。

参数 :

timer :要向调用方注册的计时器。

mode :添加计时器的模式。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/12946.html

(0)

相关推荐

  • 学习Python 3解码

    学习Python 3解码Python是一种高级编程语言,具有简洁、易读且可扩展性强的语法结构,非常适合初学者入门。在Python3中,解码是一个重要的概念。对于初学者来说,学习Python解码对于理解字符编码有重要作用,也是进一步学习其他编程语言和操作系统的必要前提。

    2024-08-27
    24
  • MySQL篇「终于解决」

    MySQL篇「终于解决」2、Mysql 的技术特点是什么? Mysql 数据库软件是一个客户端或服务器系统,其中包括:支持各种客户端程序和库的多 线程 SQL 服务器、不同的后端、广泛的应用程序编程接口和管理工具。 3、He

    2023-03-07
    149
  • Python Semaphore实现多线程同步

    Python Semaphore实现多线程同步Python是一门强大的编程语言,而且它支持多线程编程,这意味着可以利用计算机资源,提高代码的执行效率。在多线程编程中,如何解决线程安全问题是非常关键的。在本文中,我们将介绍Python Semaphore库如何实现多线程同步。

    2024-05-23
    67
  • 一文详解TDSQL PG版Oracle兼容性实践[通俗易懂]

    一文详解TDSQL PG版Oracle兼容性实践[通俗易懂]TDSQL PG版分布式关系型数据库,是一款同时面向在线事务交易和MPP实时数据分析的高性能HTAP数据库系统。面对应用业务产生的不定性数据爆炸需求,不管是高并发交易还是海量实时数据分析,TDSQL

    2023-05-02
    132
  • Python字体选择最佳实践

    Python字体选择最佳实践Python是一门强大的通用编程语言,广泛应用于Web开发、数据科学、机器学习、人工智能等领域。在Python开发中,字体选择是一个很重要的方面,它关系到代码的可读性和美观度。本文将从多个方面介绍Python字体选择的最佳实践。

    2024-02-05
    90
  • mysql的MHA高可用[通俗易懂]

    mysql的MHA高可用[通俗易懂]一.MHA简介 作者简介 松信嘉範: MySQL/Linux专家 2001年索尼公司入职 2001年开始使用oracle 2004年开始使用MySQL 2006年9月 2010年8月MySQL从事顾问

    2022-12-21
    138
  • 数据批处理是什么意思_mysql数据批处理

    数据批处理是什么意思_mysql数据批处理最近使用Spring Batch进行做数据迁移、数据同步、数据批处理等工作,感叹Spring Batch设计之简洁,对批处理编程的抽象能力之强大。 众所周知,随着大数据技术发展,企业对数据越来越重视,如何把数据有效转化为信息,以帮助企业提供数据分析、商业决策、提高核心竞争力。而…

    2023-08-03
    141
  • FreeMarker与SpringMVC的整合

    FreeMarker与SpringMVC的整合1. 背景: FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯java编写。 2. 特性 本示例实在spring的基础上整合FreeMarker,所以对于spring的部分配置不重点关注。 其中:spring-mvc.xml是spring与free…

    2023-08-02
    138

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注