NSTimer/CADisplayLink循環(huán)引用

我只是想記錄一下,設(shè)置不了文章僅自己可見?。。hit!

1.NSTimer/CAD 實現(xiàn)分類 使用block打破引用

1.1 在分類里面實現(xiàn)

在初始化timer/cadlink對象的時候,指定target的時候,會保留其目標對象,其實就是這個target。在分類中,定時器對象指定的target是timer/cadlink的類對象,這是個單例對象,因此計時器的是否保留他無所謂,因為類對象無需回收。

2. YYWeakProxy等

NSproxy本身是一個抽象類,他遵循NSObject協(xié)議,提供了消息轉(zhuǎn)發(fā)的接口。NSProxy通常來實現(xiàn)消息轉(zhuǎn)發(fā)和懶加載初始化資源。但,需要創(chuàng)建NSProxy的子類,實現(xiàn)init以及消息轉(zhuǎn)發(fā)的相關(guān)方法,才可以用。
YYWeakProxy繼承了NSProxy,定義了一個弱引用的target對象,重寫消息轉(zhuǎn)發(fā),讓target對象去處理接收到的消息,等于讓原來ViewController對象去直接處理但這里拐了一個彎,在這個彎里用弱引用解除了timer和controller的本來的強引用。

引用鏈 以下用——代表強引用 ,用---代表弱應(yīng)用

Controller——>NSTime/CADisplayLink——>YYWeakProxy--->Controller

代碼

//  NSTimer+QSTool.h
typedef void(^QSExecuteTimerBlock) (NSTimer *timer);

@interface NSTimer (QSTool)

+ (NSTimer *)qs_scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval executeBlock:(QSExecuteTimerBlock)block repeats:(BOOL)repeats;

@end

//  NSTimer+QSTool.m
@implementation NSTimer (QSTool)

+ (NSTimer *)qs_scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval executeBlock:(QSExecuteTimerBlock)block repeats:(BOOL)repeats{

    NSTimer *timer = [self scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(qs_executeTimer:) userInfo:[block copy] repeats:repeats];
    return timer;
}

+ (void)qs_executeTimer:(NSTimer *)timer{

    QSExecuteTimerBlock block = timer.userInfo;
    if (block) {
        block(timer);
    }
}

@end

//  CADisplayLink+QSTool.h
@class CADisplayLink;

typedef void(^QSExecuteDisplayLinkBlock) (CADisplayLink *displayLink);

@interface CADisplayLink (QSTool)

@property (nonatomic,copy)QSExecuteDisplayLinkBlock executeBlock;

+ (CADisplayLink *)displayLinkWithExecuteBlock:(QSExecuteDisplayLinkBlock)block;

@end

//  CADisplayLink+QSTool.m
@implementation CADisplayLink (QSTool)

- (void)setExecuteBlock:(QSExecuteDisplayLinkBlock)executeBlock{

    objc_setAssociatedObject(self, @selector(executeBlock), [executeBlock copy], OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (QSExecuteDisplayLinkBlock)executeBlock{

    return objc_getAssociatedObject(self, @selector(executeBlock));
}

+ (CADisplayLink *)displayLinkWithExecuteBlock:(QSExecuteDisplayLinkBlock)block{

    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(qs_executeDisplayLink:)];
    displayLink.executeBlock = [block copy];
    return displayLink;
}

+ (void)qs_executeDisplayLink:(CADisplayLink *)displayLink{

    if (displayLink.executeBlock) {
        displayLink.executeBlock(displayLink);
    }
}
@end

1.使用category分類

- (void)viewDidLoad {
   [super viewDidLoad];
  // ...
   __weak typeof(self) weakSelf = self;
   self.timer = [NSTimer qs_scheduledTimerWithTimeInterval:timeInterval executeBlock:^(NSTimer *timer) {
       __weak typeof(weakSelf) strongSelf = weakSelf;
       [strongSelf executeTimer:timer];
   } repeats:YES];
   [self.timer fire];
   //...
}

- (void)executeTimer:(NSTimer *)timer{
   //do something
}

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

2.使用yyweakproxy

- (void)viewDidLoad {
    [super viewDidLoad];
   // ...
    self.displayLink = [CADisplayLink displayLinkWithTarget:[YYWeakProxy proxyWithTarget:self] selector:@selector(executeDispalyLink:)];
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
   //...
}

- (void)executeDispalyLink:(CADisplayLink *)displayLink{
    //...
}

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容