iOS中NSTimer循环引用

2020-07-28  本文已影响0人  琦玉老师很强
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(fire) userInfo:nil repeats:YES];

关于这种NSTimer,如果是 repeat = YES 的定时器,没有处理就会出现循环引用的问题。
关于循环引用的原理相关文章都已经有所体现,内存泄露原理分析 ,这里简单介绍一下具体解决NSTimer循环引用的方法。

1.NSTimer提供的Block的API(self强引用timer弱引用target)

__weak typeof(self) weakSelf = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
    [weakSelf fire];
}];

2.runtime给对象添加消息处理的能力(self强引用timer强引用target)

_target = [[NSObject alloc] init];
class_addMethod([_target class], @selector(fire), class_getMethodImplementation([self class], @selector(fire)), "v@:");
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:_target selector:@selector(fire) userInfo:nil repeats:YES];

3.NSProxy消息转发的方法的方式声明一个target

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface PHJProxy : NSProxy

@property (nonatomic, weak) id target;

@end
@implementation PHJProxy

// 发送给target
- (void)forwardInvocation:(NSInvocation *)invocation {
    [invocation invokeWithTarget:self.target];
}

// 给target注册一个方法签名
- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
    return [self.target methodSignatureForSelector:sel];
}

@end

具体可以参考该文章NSProxy解决NSTimer的内存泄漏 ,另外集成YYText 可以直接使用YYTextWeakProxy引用。具体使用如下:

self.proxy = [PHJProxy alloc];
self.proxy.target = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self.proxy selector:@selector(fire) userInfo:nil repeats:YES];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[YYTextWeakProxy proxyWithTarget:self] selector:@selector(fire) userInfo:nil repeats:YES];

另外,还有一个 MSWeakTimer 也是一个不错的选择。

上一篇下一篇

猜你喜欢

热点阅读