nstimer循环引用_iOS中解决NSTimer循环引用的三种方式

逆水行舟 不进则退

今天有个人来公司面试,问了他平时在使用Timer定时器时怎么解决循环引用的问题。

然后就得到了这样一个答案:

__weak typeof(self) weakSelf = self;

self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:weakSelf selector:@selector(fire) userInfo:nil repeats:YES];

这种方式不能解决循环引用的原因是:在NSTimer的内部会对当前的weakSelf引用计数+1

声明变量

@property (nonatomic, strong, nullable) NSObject *target;

@property (nonatomic, strong, nullable) NSTimer *timer;

第一种:NSTimer提供的API

使用NSTimer提供的API,在block中执行定时任务

__weak typeof(self) weakSelf = self;

self.timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {

[weakSelf fire];

}];

引用逻辑

self强引用timer弱引用target

第二种: 借助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];

第三种:通过消息转发的方法的方式

创建一个集成自NSProxy的类PHJProxy 声明一个target

#import

#import

@interface PHJProxy : NSProxy

@property (nonatomic, weak) id target;

@end

PHJProxy的实现

@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的使用

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弱引用self

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值