NSTimer不准确的问题 cloud.tencent.com/developer/a…
后台会停止的问题。 www.jianshu.com/p/388fc8f12…
gcdtimer 耗电
<1>NSProxy:NSProxy 是一个抽象类,它接收到任何自己没有定义的方法他都会产生一个异常,所以一个实际的子类必须提供一个初始化方法或者创建方法,并且重载forwardInvocation:方法和methodSignatureForSelector:方法来处理自己没有实现的消息。 从类名来看是代理类,专门负责代理对象转发消息的。相比NSObject类来说NSProxy更轻量级,通过NSProxy可以帮助Objective-C间接的实现多重继承的功能。
.h
NS_ASSUME_NONNULL_BEGIN
@interface LGProxy : NSProxy
+ (instancetype)proxyWithTransformObject:(id)object;
@end
NS_ASSUME_NONNULL_END
.m
@interface LGProxy()
@property (nonatomic, weak) id object;
@end
@implementation LGProxy
+ (instancetype)proxyWithTransformObject:(id)object{
LGProxy *proxy = [LGProxy alloc];
proxy.object = object;
return proxy;
}
// sel - imp -
// 消息转发 self.object
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
if (self.object) {
}else{
NSLog(@"麻烦收集 stack");
}
return [self.object methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation{
if (self.object) {
[invocation invokeWithTarget:self.object];
}else{
// add imp - 动态创建 - imp
// imp 常规 -- pop
// 收集奔溃信息
NSLog(@"麻烦收集 stack");
}
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.proxy = [XZHProxy alloc];
//作为当前控制器的代理
self.proxy.obj = self;
//target为代理
self.timer = [NSTimer timerWithTimeInterval:1 target:self.proxy selector:@selector(timerEvent) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
- (void)timerEvent{
NSLog(@"%zd",self.count++);
}
- (void)dealloc{
NSLog(@"----dealloc");
//释放计时器
[self.timer invalidate];
}
<2>创建一个中间层,让timer强持有它,然后vc能正常的析构,这样定时器就可以关闭,中间层就可以释放了。
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface LGTimerWapper : NSObject
- (instancetype)lg_initWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
- (void)lg_invalidate;
@end
NS_ASSUME_NONNULL_END
@interface LGTimerWapper()
@property (nonatomic, weak) id target;
@property (nonatomic, assign) SEL aSelector;
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation LGTimerWapper
- (instancetype)lg_initWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo{
if (self == [super init]) {
self.target = aTarget;
self.aSelector = aSelector;
self.timer = [NSTimer scheduledTimerWithTimeInterval:ti target:self selector:@selector(fireHome) userInfo:userInfo repeats:yesOrNo];
}
return self;
}
- (void)fireHome{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
// 让编译器出栈,恢复状态,继续编译后续的代码!
if ([self.target respondsToSelector:self.aSelector]) {
[self.target performSelector:self.aSelector];
}
#pragma clang diagnostic pop
}
- (void)lg_invalidate{
[self.timer invalidate];
self.timer = nil;
}
- (void)dealloc{
NSLog(@"%s",__func__);
}
@end