iOS NSTimer释放方法

NSTimer释放的几种方法

  • 我们在开发过程中,总要用到定时器的功能,想必大家一般都是使用NSTimer吧(当然也不排除使用dispatch_source_t或者CADisplayLink,这两种都要比NSTimer更精确)!
    当我们在使用NSTimer时,如果销毁timer不及时就会造成循环引用导致内存泄露的问题,所以使用的时候大家都要注意使用得当!
    NSTimer销毁时我们调用invalidate方法并把timer对象置为nil;这些代码我们要写在合适的位置,dealloc析构函数才会被调用从而销毁对象.
    今天就讲讲如何正确的销毁一个NSTimer吧!
1.- (void)didMoveToParentViewController:(UIViewController *)parent;
此方法会在子视图被添加到父视图控制器或从父视图控制器移除时调用,如果是移除,参数parent为nil
- (void)didMoveToParentViewController:(UIViewController *)parent {
	if (!parent) {
    	[self.timer invalidate];
    	self.timer = nil;
	}
}
2.使用中间者
_target = [NSObject new];//id类型的属性,自己定义的中间者
Method m = class_getInstanceMethod([self class], @selector(fire));
class_addMethod([_target class], @selector(fire), method_getImplementation(m), "v@:");//运行时添加处理的方法
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:_target selector:@selector(fire) userInfo:nil repeats:YES];//创建timer
此时我们在析构函数dealloc中调用:
[self.timer invalidate];
self.timer = nil;
即可释放timer.
3.通过NSProxy作为中间者
首先创建继承自NSProxy的类WMProxy.
WMProxy.h中声明属性
@property (nonatomic ,weak) id target;
WMProxy.m中使用消息转发机制实现两个方法:
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
	return [self.target methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation {
	[invocation invokeWithTarget:self.target];
}
然后我们在需要使用NSTimer的地方引用WMProxy.h
_wmproxy = [WMProxy alloc];//WMProxy的属性
_wmproxy.target = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:_wmproxy selector:@selector(fire) userInfo:nil repeats:YES];//创建timer
此时我们在析构函数dealloc中调用:
[self.timer invalidate];
self.timer = nil;
即可释放timer.
4.使用scheduledTimerWithTimeInterval: repeats: block:方法
__weak typeof(self) weakSelf = self;
self.timer = [NSTimer wm_scheduledTimerWithTimeInterval:1 block:^{
    [weakSelf fire];
} repeate:YES];
//此方法是在iOS10.0给出的.当我们需要向下兼容版本时,我们可以通过新建分类,自己处理逻辑来实现方法调用
.h声明类方法
@interface NSTimer (WMTimer)
+ (NSTimer *)wm_scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(void(^)(void))block repeate:(BOOL)repeats;
@end

.m实现方法及调用
#import "NSTimer+WMTimer.h"
@implementation NSTimer (WMTimer)
+ (NSTimer *)wm_scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(void (^)(void))block repeate:(BOOL)repeats {
	return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(wm_blockHandle:) userInfo:block repeats:repeats];
}
+ (void)wm_blockHandle:(NSTimer *)timer {
	void(^block)(void) = timer.userInfo;
	if (block) {
    	block();
	}
}
@end
这样.NSTimer就可销毁了!
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]: \[runLoop addTimer:myTimer forMode:NSDefaultRunLoopMode\]; //实际上这步是不需要,scheduledTimerWithTimeInterval已经纳入当前线程运行。如果使用timerWithTimeInterval则需要。 引用\[2\]: \[\[NSRunLoop currentRunLoop\] addTimer:_timer forMode:NSDefaultRunLoopMode\]; //_timer = \[NSTimer scheduledTimerWithTimeInterval:1.f target:self selector:@selector(timerAction) userInfo:nil repeats:YES\]; 引用\[3\]: GCD的定时器不受RunLoop中Mode的影响(RunLoop内部也是基于GCD实现的,可以根据源码看到), 比如滚动TableView的时候,GCD的定时器不受影响;且比NSTimer更加准时。 问题: NSTimer的mode是什么意思? 回答: NSTimer的mode是指定定时器在运行时所处的运行循环模式。在使用NSTimer时,可以通过指定mode来控制定时器在哪些运行循环模式下运行。比如在引用\[1\]和引用\[2\]中,都使用了NSDefaultRunLoopMode作为定时器的运行循环模式。这意味着定时器会在默认的运行循环模式下运行。而GCD的定时器则不受RunLoop中Mode的影响,可以在任何运行循环模式下运行,如引用\[3\]所示。 #### 引用[.reference_title] - *1* [iOS多线程的初步研究(四)-- NSTimer](https://blog.csdn.net/lengshengren/article/details/12905635)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [NSTimer 基本使用和注意事项](https://blog.csdn.net/wutengwei007/article/details/82221069)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值