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(@"计时器作业中");
}

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

Objective-C的NSTimer学习笔记

+ (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(@"计时器作业中");
}

打印如下 :

Objective-C的NSTimer学习笔记

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 处理事情流程:

Objective-C的NSTimer学习笔记

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 :增加计时器的形式。