NSTimer不销毁,内存泄漏解决方案
//不调用dealloc方法
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(fire) userInfo:nil repeats:YES];
self.timer = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(fire) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
方案一,使用ViewController生命周期方法
//当从一个视图控制容器中添加或者移除viewController后,该方法被调用。
//parent:父视图控制器,如果没有父视图控制器,将为nil
-(void)didMoveToParentViewController:(UIViewController *)parent{
if (parent == nil) {
[self.timer invalidate];
self.timer = nil;
}
}
方案二,不让timer强引用self,自定义一个target,通过消息转发接收
@property (nonatomic , strong) id target;
//自定义target
self.target = [NSObject new];
//添加消息转发
class_addMethod([_target class], @selector(fire), (IMP)fireImp, "v@:");
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:_target selector:@selector(fire) userInfo:nil repeats:YES];
//消息转发函数
void fireImp (id self,SEL _cmd){
NSLog(@"fire...fire");
}
-(void)dealloc{
NSLog(@"销毁");
[self.timer invalidate];
self.timer = nil;
}
方案三,NSProxy
继承NSProxy
.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface WSProxy : NSProxy
@property (nonatomic , weak) id target;
@end
NS_ASSUME_NONNULL_END
.m
#import "WSProxy.h"
#import <objc/message.h>
@implementation WSProxy
//方法签名
-(NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
return [self.target methodSignatureForSelector:sel];
}
//转发给一个真正实现了该消息的对象
-(void)forwardInvocation:(NSInvocation *)invocation{
[invocation invokeWithTarget:self.target];
}
@end
ViewController实现方法
@property (nonatomic , strong) WSProxy *wsProxy;
_wsProxy = [WSProxy alloc];
_wsProxy.target = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:_wsProxy selector:@selector(fire) userInfo:nil repeats:YES];
-(void)dealloc{
NSLog(@"销毁");
[self.timer invalidate];
self.timer = nil;
}
网友评论