今天有我的來公司面試,問了他平時在使用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