美文网首页
NSTimer循环引用-破解五法

NSTimer循环引用-破解五法

作者: QG不吃鱼的猫 | 来源:发表于2018-12-05 16:25 被阅读38次

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

相关文章

网友评论

      本文标题:NSTimer循环引用-破解五法

      本文链接:https://www.haomeiwen.com/subject/bihicqtx.html