当前位置: 首页 > wzjs >正文

江苏建设行政主管部门网站平面设计职业学校

江苏建设行政主管部门网站,平面设计职业学校,千万别学服装设计,网页设计素材 旅游一、概述 IOS的常用的定时器有NSTimer、CADisplayLink、GCD定时器。 其中NSTimer、CADisplayLink有以下特点: 依赖RunLoop,某些方法创建时需要手动把定时器添加到RunLoop中 如果是通过target:selector方式创建的,需要注意定时器会对target…

一、概述

IOS的常用的定时器有NSTimer、CADisplayLink、GCD定时器。

其中NSTimer、CADisplayLink有以下特点:

  • 依赖RunLoop,某些方法创建时需要手动把定时器添加到RunLoop中

  • 如果是通过target:selector方式创建的,需要注意定时器会对target产生强引用。

  • 由于依赖RunLoop,如果某个RunLoop循环中有大量的耗时操作,则定时器的回掉可能不会准确的在定时间隔内触发。

GCD定时器由以下特点:

  • 依赖于操作系统内核的,定时精度相对高。

  • 不会产生循环引用问题。

二、NSTimer

2.1 使用方式

  • 通过NSInvocation封装方法签名的方式创建定时器,需要手动添加定时器到runloop中

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

  • 通过target:selector方式创建,需要手动添加定时器到runloop中(注意循环引用问题)。

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

  • 指定date时间后自动free,需要手动添加定时器到runloop中

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

  • scheduledTimerWithTimeInterval方法会自动将定时器加到RunLoop的DefaultMode中

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

2.2 BlockKit的NSTimer

利用NSTimer类对象来处理循环应用问题,将block利用userInfo进行传递到selector,再进行block回掉:

三、CADisplayLink

CADisplayLink是根据屏幕刷新率来做定时操作的,且依赖于RunLoop,也同时存在循环引用问题。CADisplayLink更多是用于一些动画、刷新率的计算。

3.1 使用方式

  • 通过displayLinkWithTarget:selector:方式创建,需要手动添加定时器到runloop中(注意循环引用问题)。

+ (CADisplayLink *)displayLinkWithTarget:(id)target selector:(SEL)sel;

  • 添加到RunLoop,除非计时器被停止,否则每次屏幕刷新时,计时器的方法都会被触发。

- (void)addToRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode;

3.2 相关属性

  • 时间戳timestamp

用来返回上一次屏幕刷新的时间戳,计算帧数可以通过 1 / (当前的时间戳-记录上一次的时间戳)。

  • 预计的下一次屏幕刷新时间戳targetTimestamp

用来返回预计下一次屏幕刷新时间戳,计算fps最好不要用这个属性,这是是预计值,与真实值有差异的.当然如果要求不严的话,也是可以用这个的,好处就是不需要记录上一次的值了,少了一个变量。

  • 间隔时间duration

默认是1 / 60,用于提供屏幕最大刷新频率(maximumFramesPerSecond)下每一帧的时间间隔。注意:是最大的 , 不是实时的帧数。

  • 修改帧率 preferredFramesPerSecond

如果在特定帧率内无法提供对象的操作,可以通过降低帧率解决.一个拥有持续稳定但是较慢帧率的应用要比跳帧的应用顺滑的多。实际的屏幕帧率会和preferredFramesPerSecond有一定的出入,结果是由设置的值和屏幕最大帧率(maximumFramesPerSecond)相互影响产生的,具体规则如下:

如果屏幕最大帧率(preferredFramesPerSecond)是60,实际帧率只能是15, 20, 30, 60中的一种.如果设置大于60的值,屏幕实际帧率为60.如果设置的是26~35之间的值,实际帧率是30.如果设置为0,会使用最高帧率。

四、dispatch_source_t

GCD定时基于系统内核,定时精度相对上面两种方式会更准确。且GCD定时器不存在对target强引用问题,不需要特别在释放的地方取消定时器。只是需要注意“self.timer = timer”,需要保住定时器的命,否则定时不会执行。

4.1 头文件SSTimer.h

//
//  SSTimer.h
//  IOSzlw
//
//  Created by zhouliangwei on 2021/10/14.
//#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface SSTimer : NSObject/// 同下面的方法,不过自动开始执行
+ (SSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;/// 创建一个定时器并返回,但是并不会自动执行,需要手动调用resume方法/// - parameter:  start 定时器启动时间/// - parameter:  ti    间隔多久开始执行selector/// - parameter:  s     执行的任务/// - parameter:  ui    绑定信息/// - parameter:  rep   是否重复
- (instancetype)initWithTimeInterval:(NSTimeInterval)start interval:(NSTimeInterval)ti target:(id)t selector:(SEL)s userInfo:(nullable id)ui repeats:(BOOL)rep;/// 扩充block
+ (SSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(SSTimer *timer))block;/// 启动
- (void)resume;/// 暂定
- (void)suspend;/// 关闭
- (void)invalidate;
@property (readonly) BOOL repeats;
@property (readonly) NSTimeInterval timeInterval;
@property (readonly, getter=isValid) BOOL valid;
@property (nullable, readonly, retain) id userInfo;
@endNS_ASSUME_NONNULL_END

4.2 实现SSTimer.m

//
//  SSTimer.m
//  IOSzlw
//
//  Created by zhouliangwei on 2021/10/14.
//#import "SSTimer.h"#import "SSTimer.h"#define lock(...) \
dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);\
__VA_ARGS__;\
dispatch_semaphore_signal(_semaphore);@implementation SSTimer {BOOL _valid;NSTimeInterval _timeInterval;BOOL _repeats;__weak id _target;SEL _selector;dispatch_source_t _timer;dispatch_semaphore_t _semaphore;id _userInfo;BOOL _running;
}
+ (SSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo {SSTimer *timer = [[SSTimer alloc] initWithTimeInterval:0 interval:ti target:aTarget selector:aSelector userInfo:userInfo repeats:yesOrNo];[timer resume];return timer;
}
+ (SSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(SSTimer *timer))block {NSParameterAssert(block != nil);SSTimer *timer = [[SSTimer alloc] initWithTimeInterval:0 interval:interval target:self selector:@selector(ss_executeBlockFromTimer:) userInfo:[block copy] repeats:repeats];[timer resume];return timer;
}
- (instancetype)initWithTimeInterval:(NSTimeInterval)start interval:(NSTimeInterval)ti target:(id)t selector:(SEL)s userInfo:(nullable id)ui repeats:(BOOL)rep {self = [super init];if (self) {_valid = YES;_timeInterval = ti;_repeats = rep;_target = t;_selector = s;_userInfo = ui;_semaphore = dispatch_semaphore_create(1);__weak typeof(self) weakSelf = self;_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());dispatch_source_set_timer(_timer, dispatch_time(DISPATCH_TIME_NOW, start * NSEC_PER_SEC), ti * NSEC_PER_SEC, 0);dispatch_source_set_event_handler(_timer, ^{[weakSelf fire];});}return self;
}
- (void)fire {if (!_valid) {return;}lock(id target = _target;)if (!target) {[self invalidate];} else {// 执行selector
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"[target performSelector:_selector withObject:self];
#pragma clang diagnostic popif (!_repeats) {[self invalidate];}}
}
- (void)resume {if (_running) return;dispatch_resume(_timer);_running = YES;
}
- (void)suspend {if (!_running) return;dispatch_suspend(_timer);_running = NO;
}
- (void)invalidate {dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);if (_valid) {dispatch_source_cancel(_timer);_timer = NULL;_target = nil;_userInfo = nil;_valid = NO;}dispatch_semaphore_signal(_semaphore);
}
- (id)userInfo {lock(id ui = _userInfo) return ui;
}
- (BOOL)repeats {lock(BOOL re = _repeats) return re;
}
- (NSTimeInterval)timeInterval {lock(NSTimeInterval ti = _timeInterval) return ti;
}
- (BOOL)isValid {lock(BOOL va = _valid) return va;
}
- (void)dealloc {[self invalidate];
}
+ (void)ss_executeBlockFromTimer:(SSTimer *)aTimer {void (^block)(SSTimer *) = [aTimer userInfo];if (block) block(aTimer);
}
@end

文章转载自:

http://KEOxrdd7.hxhrg.cn
http://nf1QxKFj.hxhrg.cn
http://M47VaRKP.hxhrg.cn
http://Vwao7fHA.hxhrg.cn
http://9Wz29HZW.hxhrg.cn
http://GJ07q95q.hxhrg.cn
http://zpS1CEAN.hxhrg.cn
http://SYgMaQZA.hxhrg.cn
http://r64tfdNC.hxhrg.cn
http://WMdO9sli.hxhrg.cn
http://Venld1pz.hxhrg.cn
http://9ppjKez9.hxhrg.cn
http://K2PL5h6f.hxhrg.cn
http://8i4TT3i1.hxhrg.cn
http://c2mxhI5c.hxhrg.cn
http://dAOeZs0Q.hxhrg.cn
http://2NCwLE40.hxhrg.cn
http://UunXMRau.hxhrg.cn
http://D6nMRhUY.hxhrg.cn
http://6L6fMt2l.hxhrg.cn
http://PqG4ZPDx.hxhrg.cn
http://6OMasqrU.hxhrg.cn
http://J2rble0q.hxhrg.cn
http://qZ2WiyQj.hxhrg.cn
http://a6pivLtb.hxhrg.cn
http://0FTXmcwU.hxhrg.cn
http://HKhfYnif.hxhrg.cn
http://3yhuunS7.hxhrg.cn
http://pObaLXmN.hxhrg.cn
http://JM505GTe.hxhrg.cn
http://www.dtcms.com/wzjs/700045.html

相关文章:

  • 网站建设费可以计入管理费用吗阿里云网站建设流程
  • 绿色设计网站泰安集团网站建设报价
  • 上海高端建站网站营销网站的成功案例
  • 南京网站设计公司有哪些公司四川省住房和城乡建设厅厅长
  • 男男床做第一次视频网站建设济南公司网站
  • 韩国网站如何切换中文猫咪mv最新地域网名怎么取
  • phpcms 网站访问统计wordpress中文视频插件下载地址
  • 临沂设计网站的公司重庆制作网站公司哪家好
  • 怎样删除网站wordpress ydg theme
  • 永久域名最新网站湛江做网站
  • 茌平网站建设菜谱制作h5链接是什么意思
  • 深圳网站建设现苏州画廊网站建设
  • 房地产设计网站网站为何站长统计
  • 网站网站是否需要备案a公司与企业k签订了建设k企业
  • 素材网站设计模板网站seo设置
  • 网站建设系统 网站自助建站系统企业信息查询系统官网湖北
  • 做网站智能工具龙岩网站建设设计服务
  • TP框架网站的中英文切换怎么做ps做图网站
  • 重庆网站建设公司推荐wordpress新站都该设置些什么
  • 代做作业网站网站 前台后台
  • 网页网站建设软件网站图片怎么做的高级
  • 专业做淘宝网站公司吗网站制作与设计
  • 江苏网站备案流程crm客户管理系统源码
  • 潍坊在线制作网站餐饮品牌设计服务
  • 建公司网站需要哪些资料网站推广app软件
  • 网站seo优化总结上海网站建设收费
  • 眉山市住房城乡建设局 网站辽宁省正规的男科医院
  • 一个公司设计网站怎么做的惠安网站建设报价
  • 社交网站开发客户谷歌关键词排名查询工具
  • 自己的网站怎么做优化网站怎么放到服务器