今天有我的来公司面试,问了他平时在使用Timer定时器时怎么解决循环引用的问题。而后就获得了这样一个答案:
面试
__weak typeof(self) weakSelf = self; self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:weakSelf selector:@selector(fire) userInfo:nil repeats:YES];
这种方式不能解决循环引用的缘由是:在NSTimer的内部会对当前的weakSelf引用计数+1atom
@property (nonatomic, strong, nullable) NSObject *target; @property (nonatomic, strong, nullable) NSTimer *timer;
使用NSTimer提供的API,在block中执行定时任务spa
__weak typeof(self) weakSelf = self; self.timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) { [weakSelf fire]; }];
引用逻辑
self强引用
timer弱引用
targetcode
引用逻辑
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];
建立一个集成自NSProxy的类PHJProxy 声明一个target图片
#import <Foundation/Foundation.h> #import <objc/runtime.h> @interface PHJProxy : NSProxy @property (nonatomic, weak) id target; @end
PHJProxy的实现get
@implementation PHJProxy // 发送给target - (void)forwardInvocation:(NSInvocation *)invocation { [invocation invokeWithTarget:self.target]; } // 给target注册一个方法签名 - (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel { return [self.target methodSignatureForSelector:sel]; } @end
PHJProxy 和 NSTimer的使用it
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强引用
proxy弱引用
selfio