iOS开发停止NSTimer循环引用的五种方法

释放双眼,带上耳机,听听看~!

NSTimer循环引用-破解五法

破解一

-(void)willMoveToParentViewController:(UIViewController *)parent {
    if(!parent){
        [self.timer invalidate];
        self.timer = nil;
    }
}

破解二 更换target

 NSObject * midOne = [[NSObject alloc] init];
    IMP imp = class_getMethodImplementation([self class], @selector(change));

    class_addMethod([midOne class], @selector(change),(IMP)imp, "v@:");

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

破解三 更换target ->NSProxy

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

WeakProxy.h

@interface WeakProxy : NSProxy

@property (nonatomic, weak, readonly) id weakTarget;
+ (instancetype)proxyWithTarget:(id)target;
- (instancetype)initWithTarget:(id)target;

@end

WeakProxy.m

#import "WeakProxy.h"

@implementation WeakProxy

+ (instancetype)proxyWithTarget:(id)target {
    return [[self alloc] initWithTarget:target];
}

- (instancetype)initWithTarget:(id)target {
    _weakTarget = target;
    return self;
}

- (void)forwardInvocation:(NSInvocation *)invocation {
    SEL sel = [invocation selector];
    if ([self.weakTarget respondsToSelector:sel]) {
        [invocation invokeWithTarget:self.weakTarget];
    }
}

//返回方法的签名。
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
    return [self.weakTarget methodSignatureForSelector:sel];
}

- (BOOL)respondsToSelector:(SEL)aSelector {
    return [self.weakTarget respondsToSelector:aSelector];
}

@end

破解四 GCD

    dispatch_queue_t queue = dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    self.timeer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);

    __weak typeof(self) weakself = self;

    dispatch_source_set_timer(self.timeer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(self.timeer, ^{
        dispatch_async(dispatch_get_main_queue(), ^{

            [weakself change];
        });
    });

    dispatch_resume(self.timeer);

破解五 NSTimer分类

    __weak typeof(self) weakself = self;
    self.timer = [NSTimer qgtimerWithTimeInterval:1.f repeats:YES block:^(NSTimer * _Nonnull timer) {
        [weakself change];
    }];
    

NSTimer+cycle.h
@interface NSTimer (cycle)

+ (NSTimer *)qgtimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block;

@end

NSTimer+cycle.m

#import "NSTimer+cycle.h"

@implementation NSTimer (cycle)

+ (NSTimer *)qgtimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block {
    
    return [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(blcokInvoke:) userInfo:[block copy] repeats:repeats];
    
}

+ (void)blcokInvoke:(NSTimer *)timer {    
    void (^block)(NSTimer *timer) = timer.userInfo;
    if (block) {
        block(timer);
    }
}

@end

人已赞赏
iOS文章

iOS开发暗黑模式适配

2021-2-4 18:09:56

iOS文章

iOS开发-WKWebView禁用HTML5的video标签默认全屏播放

2021-2-4 20:39:53

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索