1、计时器创建
1)第一种 默认直接开启
//NSTimer第一种写法
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(runTimerMethed) userInfo:nil repeats:YES];
2)第二种
@property (nonatomic,strong)NSTimer *timer;
//NSTimer第二种写法
self.timer = [NSTimer timerWithTimeInterval:1.0f target:self selector:@selector(runTimerMethed) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop]addTimer:self.timer forMode:NSRunLoopCommonModes];
- (void)runTimerMethed{
NSLog(@"计时器走了--");
}
- (void)dealloc{
NSLog(@"dealloc");
[self.timer invalidate];
self.timer = nil;
}
2、下面进行操作
当前页面为vc1,前一个页面为vc,后一个页面为vc2
1、从vc进入vc1,计时器方法开始执行,pop回vc,计时器还在跑,dealloc方法不会执行
原因:timer被runloop持有,timer释放不掉,timer又持有self,所以导致self释放不掉。不会走dealloc方法。
那就想办法~~~
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self.timer invalidate];
self.timer = nil;
}
从vc1pop回vc,可以正常dealloc了
but
从vc1进入vc2,计时器停掉了,再返回vc1,计时器开始跑,不准,pass掉该方法
3、解决方案
1)第一种:
//添加、移除进navi里执行该方法 parent = UINavigationController
- (void)didMoveToParentViewController:(UIViewController *)parent{
if (parent == nil) {
[self.timer invalidate];
self.timer = nil;
}
}
2)第二种:中间对象
原理图:
@property (nonatomic,strong)NSObject *target;
_target = [[NSObject alloc]init];
class_addMethod([_target class], @selector(runTimerMethed), (IMP)runMethedIMP, "v@:");
self.timer = [NSTimer timerWithTimeInterval:1.0f target:_target selector:@selector(runTimerMethed) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop]addTimer:self.timer forMode:NSRunLoopCommonModes];
void runMethedIMP(id self,SEL _cmd){
NSLog(@"IMP计时器走了--");
}
- (void)dealloc{
NSLog(@"dealloc");
[self.timer invalidate];
self.timer = nil;
}
3)第二种:NSProxy
橙色箭头:强引用
绿色箭头:弱引用
@interface HHProxy : NSProxy
@property (weak,nonatomic)id target;
@end
#import "HHProxy.h"
@implementation HHProxy
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
return [_target methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation{
[invocation invokeWithTarget:_target];
}
@end
调用:
_proxy = [HHProxy alloc];
_proxy.target = self;
self.timer = [NSTimer timerWithTimeInterval:1.0f target:_proxy selector:@selector(runTimerMethed) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop]addTimer:self.timer forMode:NSRunLoopCommonModes];