文档章节

iOS定时器循环引用问题解决

xiaobai1315
 xiaobai1315
发布于 2018/07/18 11:02
字数 616
阅读 9
收藏 0
iOS

我们通常使用NSTimer或CADisplayLink会使用以下方式

//定义
@property (nonatomic, strong)NSTimer *timer;

//实现
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:proxy selector:@selector(showMsg) userInfo:nil repeats:YES];

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

因为控制器强引用了timer,timer又强引用了控制器,所以会产生循环引用。

尝试解决办法:

1、把timer改成弱引用

@property (nonatomic, weak)NSTimer *timer;

虽然控制器对timer是弱引用,但是控制的delloc方法依赖于timer的invalidate,timer的invalidate又依赖于控制器的delloc方法,依旧是循环引用;

2、使用 __weak

 __weak typeof(self) weakSelf = self;
 self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:weakSelf selector:@selector(showMsg) userInfo:nil repeats:YES];

weak 关键字适用于block,当block引用了块外的变量时,会根据修饰变量的关键字来决定是强引用还是弱引用,如果变量使用weak关键字修饰,那block会对变量进行弱引用,如果没有__weak关键字,那就是强引用。

但是NSTimer的 scheduledTimerWithTimeInterval:target 方法内部不会判断修饰target的关键字,其内部会对target进行强引用,还是会产生循环引用。

最终解决办法

循环引用产生的原因就是因为A强引用B,同时B强引用A,那如果我们在A和B之间加一个C,让A强引用C,C弱引用B,B强引用A,那在B被释放后,A也会释放,就可以解决循环引用的问题;

解决方法1:

定义一个继承自NSObject的类HJProxy,在HJProxy中弱引用target

//HJProxy.h
@interface HJProxy : NSObject
+(instancetype)proxyWithTarget:(id)target;
@end


//HJProxy.m
#import "HJProxy.h"

@interface HJProxy()
@property (weak, nonatomic) id target;
@end

@implementation HJProxy

+(instancetype)proxyWithTarget:(id)target
{
    HJProxy *proxy = [[HJProxy alloc] init];
    proxy.target = target;
    return proxy;
}

//使用消息转发,将消息转发给控制器
-(id)forwardingTargetForSelector:(SEL)aSelector
{
    return self.target;
}

@end
//ViewController.m

HJProxy1 *proxy = [HJProxy1 proxyWithTarget:self];

//将timer的target设置为proxy,proxy又弱引用了控制器,其实最终还是调用了控制器的showMsg方法。
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:proxy selector:@selector(showMsg) userInfo:nil repeats:YES];

解决方法2:

使用iOS的NSProxy类,NSProxy就是专门用来做消息转发的.

//HJProxy1.h
@interface HJProxy1 : NSProxy

+(instancetype)proxyWithTarget:(id)target;

@end

//HJProxy1.m
@interface HJProxy1()
@property (weak, nonatomic)id target;
@end

@implementation HJProxy1

+(instancetype)proxyWithTarget:(id)target
{
    HJProxy1 *proxy = [HJProxy1 alloc];
    proxy.target = target;
    return proxy;
}

-(NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
    return [self.target methodSignatureForSelector:sel];
}

-(void)forwardInvocation:(NSInvocation *)invocation
{
    [invocation invokeWithTarget:self.target];
}

@end

© 著作权归作者所有

共有 人打赏支持
下一篇: iOS锁简单使用
xiaobai1315
粉丝 3
博文 203
码字总数 63315
作品 0
程序员
私信 提问
iOS查看屏幕帧数工具--YYFPSLabel

学习 YYKit 代码时,发现 ibireme 在项目里加入的一个查看当前屏幕帧数的小工具,效果如下: 挺实用,实现方法也很简单,但是思路特别棒。 这里是Demo: YYFPSLabel 这里我把这个小工具从 中...

yehot
2016/04/05
0
0
2018 iOS 面试题大全(补充完整版)

原文地址:2018 iOS 面试题大全 由于原作者并没有继续更新,这里我转过来继续更新下 这个栏目将持续更新--请iOS的小伙伴关注! 1、iOS 应用导航模式有哪些? 2、iOS 中持久化方式有哪些? 3、...

Theendisthebegi
2018/11/15
0
0
iOS与JS交互之UIWebView-JavaScriptCore框架

级别:★★☆☆☆ 标签:「iOS与JS交互」「UIWebView与JS交互」「JavaScriptCore」 作者: Xs·H 审校: QiShare团队 先解释下标题:“iOS与JS交互”。iOS指原生代码(文章只有示例),JS指前...

QiShare
2018/08/30
0
0
iOS与JS交互之UIWebView-JSExport协议

级别:★★☆☆☆ 标签:「iOS与JS交互」「UIWebView与JS交互」「JSExport」 作者: Xs·H 审校: QiShare团队 先解释下标题:“iOS与JS交互”。iOS指原生代码(文章只有示例),JS指前端(不...

QiShare
2018/08/31
0
0
iOS中使用schema协议调用APP和使用iframe打开APP的例子

在iOS中,需要调起一个app可以使用schema协议,这是iOS原生支持的,并且因为iOS系统中都不能使用自己的浏览器内核,所以所有的浏览器都支持,这跟android生态不一样,android是可以自己搞内核...

BearCatYN
2015/06/12
0
1

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周一乱弹 —— 白掌柜说了卖货不卖身

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @爱漫爱 :这是一场修行分享羽肿的单曲《Moony》 手机党少年们想听歌,请使劲儿戳(这里) @clouddyy :开不开心? 开心呀, 我又不爱睡懒觉…...

小小编辑
今天
7
0
大数据教程(11.7)hadoop2.9.1平台上仓库工具hive1.2.2搭建

上一篇文章介绍了hive2.3.4的搭建,然而这个版本已经不能稳定的支持mapreduce程序。本篇博主将分享hive1.2.2工具搭建全过程。先说明:本节就直接在上一节的hadoop环境中搭建了! 一、下载apa...

em_aaron
今天
2
0
开始看《JSP&Servlet学习笔记》

1:WEB应用简介。其中1.2.1对Web容器的工作流程写得不错 2:编写Servlet。搞清楚了Java的Web目录结构,以及Web.xml的一些配置作用。特别是讲了@WebServlet标签 3:请求与响应。更细致的讲了从...

max佩恩
今天
4
0
mysql分区功能详细介绍,以及实例

一,什么是数据库分区 前段时间写过一篇关于mysql分表的的文章,下面来说一下什么是数据库分区,以mysql为例。mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可...

吴伟祥
今天
3
0
SQL语句查询

1.1 排序 通过order by语句,可以将查询出的结果进行排序。放置在select语句的最后。 格式: SELECT * FROM 表名 ORDER BY 排序字段ASC|DESC; ASC 升序 (默认) DESC 降序 1.查询所有商品信息,...

stars永恒
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部