iOS便利NSTimer

為什么要寫這篇破事水

這些代碼來自于年初某短視頻巨廠面試時候的即興表演腹侣,
當時寫的是偽代碼叔收,現(xiàn)在把他補完整
面試官提出來的要求如下:


NSTimer用起來有很多注意點,不方便傲隶,要求實現(xiàn)一個
+ (NSTimer *)xx_scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

1.解決循環(huán)引用
2.aTarget釋放時自動invalidate
3.多個timer可以同時存在


那他滿意了嗎

看他笑的挺滿意的饺律,那一輪面試也確實過了,可惜二面沒表現(xiàn)好……我懷疑是被白剽思路(不可能的你想太多了)

那在哪里可以拿到demo呢伦籍?

GitHub - DTD1031/EasyTimer

那怎么實現(xiàn)

當時思考了2分鐘拿出以下方案蓝晒,大致就是用了備用接收者和完整消息轉(zhuǎn)發(fā)來完成這個方法腮出,貼一點關(guān)鍵代碼帖鸦,完整demo代碼在上面的github里

  1. NSTimer+Easy方法
+ (NSTimer *)clc_scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo {

    CLCTimerObject *obj = [[CLCTimerObject alloc] init];
    obj.target = aTarget; //weak
    obj.myTimer = [NSTimer scheduledTimerWithTimeInterval:ti target:obj selector:aSelector userInfo:userInfo repeats:yesOrNo];
    //timer 持有obj,obj弱引用aTarget胚嘲,obj同時也負責處理aTarget釋放時timer的invalidate
    return obj.myTimer;
}

2.CLCTimerObj屬性

//一個持有aTarget作儿,一個持有timer,都是弱引用馋劈,反正timer啟動了就會被掛住
@property (nonatomic, weak) NSObject *target;
@property (nonatomic, weak) NSTimer *myTimer;

3.CLCTimerObj實現(xiàn)
//用runtime的備用接收者機制去判斷aTarget釋放了沒

- (id)forwardingTargetForSelector:(SEL)aSelector {
    //target還沒釋放  --> 返回的是self.target對象
    //target被釋放了  --> 返回的是nil攻锰,進入下一步消息轉(zhuǎn)發(fā)
    NSLog(@"send to aTarget");
    return self.target;
}

//用完整消息轉(zhuǎn)發(fā)兜底,上一步返回nil時就invalidate掉timer

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    NSLog(@"return Signature");
    return [NSMethodSignature signatureWithObjCTypes:"v@:@@"]; //隨便簽妓雾,無所謂啦
}

- (void)forwardInvocation:(NSInvocation *)invocation {
    NSLog(@"call forwordInvocation");
    [self _invalidateTimer];
}


- (void)_invalidateTimer {
    if (self.myTimer) {
        [self.myTimer invalidate];
        self.myTimer = nil;
    }
}

利弊分析

好處

1.防止發(fā)生循環(huán)引用娶吞、timer沒有好好手動invalidate等問題,傻瓜式timer(只是做保護械姻,還是建議手寫invalidate)

2.一次性倒計時View(比如543210開始直播)不需要把timer掛住當屬性妒蛇,時間到了自己removeFromSuperview引用計數(shù)歸零變成nil就行了,不需要管timer楷拳,他是自動的

3.自動停止能確保NSTimer的invalidate和init在同一個線程里

孬處
  1. 維護起來不容易閱讀(“我艸這timer啥時候釋放的绣夺?”)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市欢揖,隨后出現(xiàn)的幾起案子陶耍,更是在濱河造成了極大的恐慌,老刑警劉巖她混,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烈钞,死亡現(xiàn)場離奇詭異,居然都是意外死亡坤按,警方通過查閱死者的電腦和手機毯欣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晋涣,“玉大人仪媒,你說我怎么就攤上這事。” “怎么了算吩?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵留凭,是天一觀的道長。 經(jīng)常有香客問我偎巢,道長蔼夜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任压昼,我火速辦了婚禮求冷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窍霞。我一直安慰自己匠题,他們只是感情好,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布但金。 她就那樣靜靜地躺著韭山,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冷溃。 梳的紋絲不亂的頭發(fā)上钱磅,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機與錄音似枕,去河邊找鬼盖淡。 笑死,一個胖子當著我的面吹牛凿歼,可吹牛的內(nèi)容都是我干的褪迟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼毅往,長吁一口氣:“原來是場噩夢啊……” “哼牵咙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起攀唯,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤洁桌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后侯嘀,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體另凌,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年戒幔,在試婚紗的時候發(fā)現(xiàn)自己被綠了吠谢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡诗茎,死狀恐怖工坊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤王污,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布罢吃,位于F島的核電站,受9級特大地震影響昭齐,放射性物質(zhì)發(fā)生泄漏尿招。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一阱驾、第九天 我趴在偏房一處隱蔽的房頂上張望就谜。 院中可真熱鬧,春花似錦里覆、人聲如沸丧荐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽篮奄。三九已至捆愁,卻和暖如春割去,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背昼丑。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工呻逆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人菩帝。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓咖城,卻偏偏與公主長得像,于是被迫代替她去往敵國和親呼奢。 傳聞我的和親對象是個殘疾皇子宜雀,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355