Tips:NSTimer需要注意的兩個(gè)小問(wèn)題

1、scrollView滾動(dòng)時(shí)NSTimer暫停的問(wèn)題

便利構(gòu)造方法 + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;會(huì)將timer直接綁定到NSDefaultRunLoopMode,而在scrollView滾動(dòng)的時(shí)候處于UITrackingRunLoopMode下,是不會(huì)處理NSRunLoopDefaultMode的消息的,因此此時(shí)應(yīng)該手動(dòng)添加timer到NSRunLoopCommonModes下面。

timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(doSomething) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

2、UIView的NSTimer內(nèi)存釋放

如果你的View有一個(gè)property:

@property(nonatomic, strong) NSTimer *timer;

然后你初始化并執(zhí)行一個(gè)循環(huán)動(dòng)畫(huà)

- (void)start
{
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES];
}

-(void)handleTimer:(NSTimer *)theTimer
{
    // 動(dòng)畫(huà)
}

你應(yīng)該知道NSTimer需要invalidate才能使得view能夠dealloc。但是這樣寫(xiě)是自欺欺人的做法:

- (void)stopTimer
{
    [self.timer invalidate];
    self.timer = nil;
}

- (void)dealloc
{
    [self stopTimer];
}

你陷入了雞生蛋,蛋生雞的悖論中。。。你要view死,然后才invalidate,但是view非要等到你invalidate才能死啊!如果你又不想在外面顯示的調(diào)用stopTimer,那么這樣做比較合適,在view移除出視圖結(jié)構(gòu)的時(shí)候

- (void)willMoveToSuperview:(UIView *)newSuperview
{
    if (!newSuperview)
    {
        [self stopTimer];
    }
}

另外也可以參照《Effective Objective-C 2.0》書(shū)中的做法:采用block的方式,推薦用這種,ios 10中已經(jīng)提供了這個(gè)API了。

@interface NSTimer (OVExtension)

// 避免 timer 循環(huán)引用,自動(dòng)釋放
// ios 10 已經(jīng)有了這個(gè) api,但是 ios8 和 ios9 不支持
+ (instancetype)ov_scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)())block;

@end

@implementation NSTimer (OVExtension)

+ (instancetype)ov_scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)())block
{
    return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(ov_blockInvoke:) userInfo:[block copy] repeats:repeats];
}

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

@end

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

相關(guān)閱讀更多精彩內(nèi)容

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