NSTimer 循环引用分析与解决方案

打破NSTimer的循环引用 说到Timer定时器不得不说说,Timer造成的循环引用。当我们跳转到一个VC时,在这个VC创建一个重复触发的定时器,当从这个VC返回时,发现VC的delloc方法并未调用,这是因为timer对VC的强引用导致VC无法释放。 解决这中问题的关键就是让Timer解除对VC的强引用。 首先想到的: 1.破除循环引用只要断开一方就可以了呀?所以在VC中把Timer的属性修饰符,由strong变... 阅读详情

NSTimer循环引用分析

下面的方法可以创建计时器,并将其预先安排到当前运行循环(Run Loop)当中:

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

参数target和selector表示计时器将在哪个对象上调用哪个方法,repeats表示是否重复执行任务。
计时器会保留其目标对象,等到自身“失效”时再释放此对象。
(1)当repeats设置为NO时,执行完相关任务之后,计时器会自动失效;
(2)当调用invalidate方法时,可以令计时器失效;
因此将计时器设置成重复模式时,很容易导致“循环引用”的问题,必须自己调用invalidate方法,才能停止计时器。

NSTimer循环解决方案

 第一种方法

- (void)viewDidLoad {
    [super viewDidLoad];
    _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(startTimer) userInfo:nil repeats:YES];
}

-(void)startTimer{
    NSLog(@"timer ok");
}

#pragma mark 第一种方法:在合适时机
- (void)didMoveToParentViewController:(UIViewController *)parent{
    if (parent == nil) {
        [_timer invalidate];
        _timer = nil;
    }
}

-(void)dealloc{
    NSLog(@"%@ dealloc",[self class]);  
}

 第二种方法(消息转发机制)

@interface ViewController2 ()

@property (nonatomic,strong) NSTimer  *timer ;
@property (nonatomic,strong) NSObject  *target ;

@end

@implementation ViewController2

-(void)dealloc{
    NSLog(@"%@ dealloc",[self class]);
    [_timer invalidate];
    _timer = nil;

}

- (void)viewDidLoad {
    [super viewDidLoad];
    _target = [NSObject new];
    class_addMethod([_target class], @selector(startTimer), class_getMethodImplementation([self class], @selector(startTimer)), "v@:");
    _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:_target selector:@selector(startTimer) userInfo:nil repeats:YES];
}

-(void)startTimer{
    NSLog(@"timer ok");
}

@end

第三种方法(NSProxy)

@interface MyProxy : NSProxy

@property(nonatomic,weak) id target;

@end

@implementation MyProxy

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { 
    return [self.target methodSignatureForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)invocation {
    
    if ([self.target respondsToSelector:invocation.selector]) {
        [invocation invokeWithTarget:self.target];
    }
}

@end


#import "MyProxy.h"

@interface ViewController2 ()

@property (nonatomic,strong) NSTimer  *timer ;
@property (nonatomic,strong) MyProxy  *targetProxy ;

@end

@implementation ViewController2

-(void)dealloc{
    NSLog(@"%@ dealloc",[self class]);
    [_timer invalidate];
    _timer = nil;

}

- (void)viewDidLoad {
    [super viewDidLoad];
    _targetProxy = [MyProxy alloc];
    _targetProxy.target = self;
    _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:_targetProxy selector:@selector(startTimer) userInfo:nil repeats:YES];
}

-(void)startTimer{
    NSLog(@"timer ok");
}
 

@end

第四种方法(苹果API接口解决方案(iOS 10.0以上))

在iOS 10.0以后,苹果官方新增了关于NSTimer的三个API:

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

- (instancetype)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

这三个方法都有一个Block的回调方法。关于block参数,官方文档有说明:

the timer itself is passed as the parameter to this block when 
executed to aid in avoiding cyclical references。

翻译过来就是说,定时器在执行时,将自身作为参数传递给block,来帮助避免循环引用。
使用很简单,就不再举例了,使用时注意两点:

  1. 避免block的循环引用(使用__weak和__strong来避免);
  2. 在持用NSTimer对象的类的方法中-(void)dealloc调用NSTimer 的- (void)invalidate方法;

 

iOS开发-NSTimer探究 NSTimer 的使用 1、NSTimer 的创建 我们经常会使用下面四种常用的 NSTimer 的创建方法,都是类方法。 Target-action: + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)... 阅读详情

相关推荐

深入Objective-C:类加载、初始化与NSTimer的使用

本文深入探讨了Objective-C中类加载和初始化的过程,重点讲述了load和initialize方法的特性、用途以及它们之间的区别。同时,文章还详细分析了NSTimer的使用细节,包括它如何与run loop交互,以及定时器保留目标对象可能导致的循环引用问题,并提供了相应的解决方案。

weixin_35592186的博客 609

NSTimer循环引用

NSTimer循环引用

qq_40319342的博客 1064

iOS如何巧妙解决NSTimer的循环引用详解

主要给大家介绍了关于iOS如何巧妙解决NSTimer的循环引用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

NSTimer解决循环引用常见方法

NSTimer,循环引用

qq_35508084的博客 1128

FC游戏金手指代码大全:亲测可用指南与内存修改原理

在计算机和游戏开发领域,内存修改是一项基础而强大的技术,它通过直接读写程序运行时内存中的数据,改变软件的行为和状态。其核心原理在于理解进程的内存地址空间布局,定位存储关键游戏变量(如生命值、金币数)的特定地址,并注入或锁定目标数值。这项技术的工程价值在于,它不仅能用于游戏辅助,更是软件逆向工程、漏洞分析和调试的重要实践手段。在怀旧游戏和模拟器场景中,内存修改以“金手指”或“作弊码”的形式广泛应用,帮助玩家自定义游戏体验。本文将聚焦FC(红白机)游戏,深入解析Game Genie码和Raw码两种主流金手指格式

weixin_30780649的博客 782

FDTD仿真进阶:液晶偏振调控与双折射效应全解析

本文深入解析了在Lumerical FDTD仿真中如何对液晶材料进行偏振调控与双折射效应建模。通过单轴液晶和螺旋扭曲液晶(TN-LCD)两大实战案例,详细阐述了从各向异性材料参数设置、LC网格属性配置到偏振椭圆分析的全流程,帮助工程师精准模拟液晶的光开关行为,优化如显示器等器件的光学性能。

chair的专栏 745

python pandas.read_csv读取每行的列数不同csv文件或txt文件

解决方法:使用read_csv方法时,通过names属性设置多指定一些列名。 df = pd.read_csv(txt_or_csv_filename,header=None,index_col=False,names=['a','b','c','d','e'])

fmber的博客 4875

NumPy包(下) python笔记扩展

nditer 是 NumPy 中的一个强大的迭代器对象,用于高效地遍历多维数组。nditer 提供了多种选项和控制参数,使得数组的迭代更加灵活和高效。nditer 提供了多种控制参数,用于控制迭代的行为。1.order 参数order 参数用于指定数组的遍历顺序。默认情况下,nditer 按照 C 风格(行优先)遍历数组。# 创建一个二维数组​# 使用 C 风格遍历数组print(x)# 输出:# 1# 2# 3# 4# 5# 6​# 使用 Fortran 风格遍历数组。

正在学习中ing...... 1353

NSTimer 引发的循环引用(内存泄漏)| NSTimer强引用

在iOS中使用NSTimer(定时器)不当会引发内存泄漏.我这里主要讲使用NSTimer 会引发的内存泄漏情况以及解决方法:内存泄漏出现的场景:VC A push 到VC B, VC B里启动了一个 NSTimer, 然后VC B push 到VC C (或者 pop 回VC A), 此时 VC B里的 NSTimer 仍在执行(这是不对的),造成的原因就是 VC B里的 NSTimer 没有被及时释放(销毁)掉,我们称之为内存泄漏.

wyz670083956的博客 1435

功能安全入门:手把手教你用IEC 62380标准计算芯片失效率(附SN 29500对比)

本文深入解析了IEC 62380标准在芯片失效率计算中的应用,对比了SN 29500的差异,并提供了实战案例和避坑指南。通过详细的参数获取方法和分步计算演示,帮助功能安全工程师准确评估芯片可靠性,确保设计符合安全要求。特别适合汽车电子和工业控制领域的专业人士参考。

weixin_30363981的博客 315

SwarmClaw:自托管多智能体AI运行时部署与实战指南

多智能体系统是人工智能领域的重要发展方向,它通过多个具备自主决策和协作能力的智能体共同完成任务,其核心原理在于分布式问题求解与协同规划。这种架构在提升任务处理效率、复杂问题分解和鲁棒性方面具有显著技术价值,广泛应用于自动化工作流、虚拟团队协作、智能客服和个性化助手等场景。本文聚焦于SwarmClaw这一自托管的多智能体AI运行时,它原生支持Model Context Protocol,并内置了超过23种AI提供商,为开发者提供了一个开箱即用且高度可定制的控制平面,便于构建和管理复杂的多智能体协作网络。

weixin_27207591的博客 401

Java 四种引用

截止现今版本,Java的引用分为四种:强引用、软引用、弱引用和虚引用(又称幽灵引用),在JDK1.2中引入了这四种引用,使得开发中可以在一定程度上虚范围的控制Java对象的生命周期。之所以说虚范围,是因为即使使用了非强引用,最终的垃圾回收发起也都是由JVM垃圾回收机制决定的,但是这种改变是一种进步,使我们在应用中更加灵活。 强引用: 一般在Java开发中使用的都是强引用,之所以称之为

键盘上流淌的日子 9333

通过两个mark点确定某一个点的位置

read_image (Image0, '0.bmp') binary_threshold (Image0, Region, 'max_separability', 'dark', UsedThreshold) connection (Region, ConnectedRegions) fill_up (ConnectedRegions, RegionFillUp) select_shape_std (RegionFillUp, SelectedRegions, 'max_area', 70) red...

优快云博客 3887

内存管理——NSTimer循环引用讲解

NSTimer循环引用例子 循环引用代码 @interface ViewController () @property (strong, nonatomic) NSTimer *timer; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // [NSRunLoop currentRunLoop] 对 timer 的强持有 self.timer = [NST

Z1591090的博客 599

手把手教你用SIMCOM A7670C_FASL模组实现双路MQTT连接阿里云(附完整源码)

本文详细介绍了如何使用SIMCOM A7670C_FASL 4G模组实现双路MQTT连接阿里云,包括硬件配置、开发环境搭建、双路MQTT架构设计及实现细节。通过完整的源码示例和实战指南,帮助开发者快速掌握物联网设备开发中的多路MQTT连接技术,提升工业级应用的开发效率。

weixin_33696822的博客 227

核磁共振常用的文件格式介绍:NIfTI volume 格式 (*.nii), GIFTI 格式 (*.gii), CIFTI 格式 (*.nii)

NIfTI volume 格式 (*.nii)GIFTI 格式 (*.gii)CIFTI 格式 (*.nii)Scene file文件 (*.scene)规格文件 (*.spec)解剖 (*.annot)一个场景文件包含一个或多个场景;每个场景实际上是保存时 wb_view 内部状态的快照。这包括有关加载哪些文件、如何显示、如何配置选项卡的信息(选择了哪些表面、在每个层中选择了哪些文件、打开了哪些层、哪些视图旋转、调色板设置、平铺选项卡等),以及在它们上面添加了哪些注释(文本、箭头、圆圈等)。

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 3043

nstimer循环引用_iOS之NSTimer循环引用的解决方案

前言在使用NSTimer,如果使用不得当特别会引起循环引用,造成内存泄露。所以怎么避免循环引用问题,下面我提出几种解决NSTimer的几种循环引用。原因当你在ViewController(简称VC)中使用timer属性,由于VC强引用timer,timer的target又是VC造成循环引用。当你在VC的dealloc方法中销毁timer,发现VC被pop,VC的dealloc方法没走,VC在等ti...

weixin_39866817的博客 306

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

解决NSTimer循环引用Retain Cycle问题

解决NSTimer循环引用Retain Cycle问题 iOS开发中以下的情况会产生循环引用 block delegate NSTimer 循环引用导致一些对象无法销毁,一定的情况下会对我们横须造成影响,特别是我们要在dealloc中释放一些资源额时候,本篇主要解决NSTimer引起的循环引用问题。 问题分析 主要由于NSTimer对象和调用NSTimer的视图控制器对象相互强引用了...

weixin_30929011的博客 272

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

修复iCarousel内存泄漏:NSTimer与Delegate循环引用深度解析

你是否遇到过iOS应用滑动卡顿、界面无响应,最终发现是内存泄漏导致的崩溃?本文通过iCarousel开源项目实例,详解两种最隐蔽的内存泄漏场景,提供完整解决方案和预防措施。读完本文你将掌握:NSTimer内存管理最佳实践、Delegate弱引用实现方法、内存泄漏检测工具使用技巧。 ## 内存泄漏场景分析 iCarousel作为iOS和macOS平台的3D轮播组件([iCarousel/iCar...

gitblog_01176的博客 501

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

内存管理(4) - 循环引用

当用指针指向某个对象时候,可以对其进行管理(通过retain和release)就拥有对这个对象的强引用或弱引用 1、什么是循环引用? 结论: 当两个对象相互持有对方(即拥有对对方的强引用),此时各自的引用计数都为1,释放不了,而造成内存泄露。 当多个对象能形成一个环时候情况类似。 用weak或者__weak创建归零弱引用 因为c指向的地方被释放了,调用它可能会导致问题,...

swel的博客 465

iOS NSTimer 循环引用

高逼格解决NSTimer定时器中循环引用

仰望星空的博客 774

ios开发-解决定时器循环引用

前言: 对iOS开发者的忠告:在这个技术不断更迭的互联网时代,作为一个iOS开发者如果变成语言只掌握OC是远远不够的,如果是这种情况,你也很容易被淘汰。博主希望iOS开发者也学会一门后台语言,无论是PHP,或者是JAVA,或者其他。不然,你在公司永远没有地位。 本章主要介绍swift语言 swift–》苹果于2014年WWDC(苹果开发者大会)发布的新开发语言。作为一个iOS开发者也是必须熟练掌握......

逝水无情的博客 1203

iOS中解决NSTimer循环引用问题

NSTimer使用不当就会造成内存泄漏,比如常见的使用方法: //定义 @property (nonatomic, strong) NSTimer *timer; //实现 self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(showMsg) userInfo:nil repeats:YES]; //销毁 -(void)dealloc { [self.timer inval

u013712343的博客 914

NSTimer引用问题

原文:https://www.jianshu.com/p/878bfd38666d NSTimer 对于 target 的循环引用问题: 以下代码很常见: CADisplayLink *_link = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)]; [NSTimer timerWithT

leeqiang250的专栏 350

内存管理:CADisplayLink、NSTimer、NSProxy 使用注意

CADisplayLink、NSTimer 会对target 产生强引用,如果target 又对他们产生了强引用,那么就会引发循环引用。 总结: CADisplayLink 想要返回界面就销毁定时器,可以使用 一个 中间代理 NSTimer 则可以使用 block 和 中间代理 中间代理 可以使用继承至 NSObject 或 NSProxy NSProxy 是什么? 继承至 NSObjec...

M316625387的博客 541

NSTimer 使用注意事项

NSTimer 是系统提供的定时器,系统提供的api也比较简单,使用很方便,项目开发中会经常用到。然而,在使用NSTimer时,如果不注意,非常容易引起内存泄露的问题。本文总结了下NSTimer 引起内存泄露问题的原因,以及解决方案。 NSTimer的使用 通常情况下,NSTimer 是作为controller或者view的一个属性来使用: /** gif播放的定时器 */ @p...

TuGeLe的博客 1430
上一篇: 响应链遇到手势,问题分析
下一篇: NSTaggedPointerString,__NSCFConstantString,__NSCFString和NSString的关系?NSString为什么用copy?
LIN1986LIN
博客等级 码龄19年 17粉丝 93原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值