iOS开发系列-定时器强引用问题
概述
iOS开发中常用的定时器NSTimer、CADisplayLink。
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];
iOS开发系列-定时器强引用问题的更多相关文章
- iOS开发系列--Swift进阶
概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...
- iOS开发系列之app的一天
本文主要讲述我对 iOS 开发的一些理解,希望能通过 app 从启动到退出,将一些的知识整合起来,形成一条知识链,目前涉及到的知识点有 runloop.runtime.文件存储.界面布局.离线推送.内 ...
- iOS开发系列--数据存取
概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...
- iOS开发系列--C语言之基础知识
概览 当前移动开发的趋势已经势不可挡,这个系列希望浅谈一下个人对IOS开发的一些见解,这个IOS系列计划从几个角度去说IOS开发: C语言 OC基础 IOS开发(iphone/ipad) Swift ...
- iOS开发系列--让你的应用“动”起来
--iOS核心动画 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建 ...
- iOS开发系列--让你的应用“动”起来
--iOS核心动画 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建 ...
- 【转】iOS开发系列--数据存取
原文: http://www.cnblogs.com/kenshincui/p/4077833.html#SQLite 概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储 ...
- IOS开发系列 --- 核心动画
原始地址:http://www.cnblogs.com/kenshincui/p/3972100.html 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥i ...
- iOS开发系列--让你的应用“动”起来【转载】
概览 原文链接:http://www.cnblogs.com/kenshincui/p/3972100.html 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥i ...
随机推荐
- 拾遗:btrfs
#扫描 btrfs 文件系统btrfs device scan btrfs device scan /dev/sda #创建子卷或快照 btrfs subvolume create /mnt/btrf ...
- 拾遗:Go 代码结构
#define @ $ 概述 Go 编码通常将所有代码放置在同一个工作区 一个工作区包含多个版本仓库,使用 Git 等工具控制 每个仓库包含一个或多个包 每个包由同一目录中的一份或多份源代码组成 包的 ...
- explain分析sql语句执行效率
Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 果,可以帮助选择更好的索引和优化查询语句,写出更好的优 ...
- mybatis执行test07测试类却显示test05测试类调用的sql语句出错
1.测试类 @Test public void test07() { IStudentDao studentDao = new IStudentDaoImpl(); Student student = ...
- 条件sql ibatis
<!-- 多条件查询 --><select id="MS-CUSTOM-PANDECT-INFO-BY-CONDITIONS" resultMap="R ...
- 第二记 Java数据类型
一.数据类型 java中数据类型分为基本数据与引用数据类型两大类,其中又有更细致的划分,下面以图展示 二.基本数据类型封装类 Java是一门面向对象的语言,但是在一些情况下基本数据类型无法满足Java ...
- $.Deferred 对象详解
1.什么是deferred对象? 开发网站的过程中,我们经常遇到某些耗时很长的javascript操作.其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们 ...
- 从零开始搭建系统1.4——MySql安装及配置
安装环境:CentOS7 64位 ,安装MySQL5.7 1.创建mysql目录 2.在MySQL官网中下载YUM源rpm安装包:http://dev.mysql.com/downloads/repo ...
- Java微服务(Spring-boot+MyBatis+Maven)入门教程
1,项目创建 新建maven项目,如下图: 选择路径,下一步 输入1和2的内容,点完成 项目创建完毕,结构如下图所示: 填写pom.xml里内容,为了用于打包,3必须选择jar,4和5按图上填写 ...
- Apache Tomcat下载、安装、环境变量配置以及项目部署
前言 针对在本地访问文件或资源出现的跨域问题,可以通过搭建本地服务器来解决,本篇随笔主要介绍通过搭建Apache Tomcat服务器来解决跨域.包括Apache Tomcat的下载.安装.环境变量的配 ...