概述

iOS开发中常用的定时器NSTimerCADisplayLink

NSTimer 和 CADisplayLink 基本使用

NSTimer的创建方法有两个scheduledTimerWithTimeInterval开头另一个直接timerWithTimeInterval

// scheduled开头创建的定时器默认已经添加到RunLoop中
self.timer =[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(testTimer) userInfo:nil repeats:YES]; NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(testTimer) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

CADisplayLink创建方法displayLinkWithTarget创建

CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(testLink)];
[link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

定时器强引用问题

在开发中在将通常将控制器作为定时器的target。一般我们在控制器的dealloc方法中停止定时器。

- (void)dealloc
{
[self.timer invalidate];
}

由于将控制器设置为定时器的target,定时器会对控制器做强引用,造成控制器在pop出栈不会销毁,也不会调用控制器的的dealloc的方法,控制器pop后,定时器依然执行。

避免设置target强引用解决方案

方案一

由于NSTimer可以通过block的方式直接设置定时任务可以避免设置target引起的强引用。

[NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
// 定时任务
}];

方案二

创建一个代理TimerProxy,将代理作为定时器target。

TimerProxy.h

#import <Foundation/Foundation.h>

@interface HTTimerProxy : NSObject
+ (instancetype)timerProxyWithTaget:(id)target;
@property (nonatomic, weak) id target;
@end TimerProxy.m #import "HTTimerProxy.h" @implementation HTTimerProxy + (instancetype)timerProxyWithTaget:(id)target
{
HTTimerProxy *proxy = [[self alloc] init];
proxy.target = target;
return proxy;
} // 利用runtime的消息转发
- (id)forwardingTargetForSelector:(SEL)aSelector
{
return self.target;
}
@end

NSTimer与CADisplayLink将HTTimerProx作为代理

// scheduled开头创建的定时器默认已经添加到RunLoop中
self.timer =[NSTimer scheduledTimerWithTimeInterval:1.0 target:[HTTimerProxy timerProxyWithTaget:self] selector:@selector(testTimer) userInfo:nil repeats:YES]; CADisplayLink *link = [CADisplayLink displayLinkWithTarget:[HTTimerProxy timerProxyWithTaget:self] selector:@selector(testLink)];
[link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

最新文章

  1. ubuntu命令
  2. SQL语言分类
  3. visual studio 查找/替换对话框
  4. Android NDK之JNI陷阱
  5. Chrome插件开发
  6. 修改LR自带的示例程序端口号
  7. ThreadLocal的基本原理与实现
  8. 一个Java对象到底占用多大内存
  9. KP 佛学禅语
  10. 【深圳,武汉】一加科技(One Plus)招聘,寻找不...
  11. JavaScript易错点转载
  12. vue监听滚动事件,实现滚动监听
  13. hihoCoder #1043 : 完全背包(板子题)
  14. RDS和ROS使用小结
  15. 不错的东西: AutoMapper
  16. FT 软件项目管理
  17. ColumnStore完整验证指南之安装与启动停止
  18. MFC 的资源文件 就是那个后缀名是 .rc的那个
  19. Java IO流学习总结二:File
  20. leetcode 中等题(1)

热门文章

  1. nginx502问题
  2. Spring 学习笔记 Resource 资源
  3. Pandas重复值处理
  4. 使ie6/7/8支持css3的方法
  5. &lt;Linux&gt;Linux基础学习(兄弟连版本)
  6. js进阶之路,关于UI资源的优化(转载)
  7. java heap space以及jvisualvm.exe 工具
  8. LGV定理 (CodeForces 348 D Turtles)/(牛客暑期多校第一场A Monotonic Matrix)
  9. Mysql事务学习笔记
  10. scala中的闭包