码迷,mamicode.com
首页 > 其他好文 > 详细

OC原理解决定时器的循环引用

时间:2021-02-26 13:22:00      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:声明   self   import   repeat   问题   spl   isp   sel   没有   

对于以下代码:

@property (strong, nonatomic) NSTimer *timer;

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

- (void)timerTest
{
    NSLog(@"%s", __func__);
}

- (void)dealloc
{
    [self.timer invalidate];
}

运行代码之后,发现当前对象并没有销毁,定时器并没有销毁,其实是由于当前对象对timer进行强引用,而timer中的target又对当前对象进行强应用,导致循环引用

解决这种循环引用的有两种,一个timer创建的时候用block代码如下,并声明weakSelf属性,代码如下:

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

第二种创建一个中间对象,里面声明一个weak的target的对象,再利用runtime的转发机制,有target去执行

创建LBTemp的类,代码如下:

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface LBTemp : NSObject
+ (instancetype)tempWithTarget:(id)target;
@property (weak, nonatomic) id target;
@end

#import "LBTemp.h"

@implementation LBTemp
+ (instancetype)tempWithTarget:(id)target
{
    LBTemp *temp = [[LBTemp alloc] init];
    temp.target = target;
    return temp;
}

- (id)forwardingTargetForSelector:(SEL)aSelector
{
    return self.target;
}
@end

创建timer代码如下:

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

同样的CADisplayLink循环引用问题也可以用第二种方法解决

 

OC原理解决定时器的循环引用

标签:声明   self   import   repeat   问题   spl   isp   sel   没有   

原文地址:https://www.cnblogs.com/muzichenyu/p/14449413.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!