如何打破NSTimer與Target之間的Retain Cycle

NSTimer

NSTimerFoundation框架中一種很方便很有用的對(duì)象兵迅,可以:

  • 指定絕對(duì)的日期和時(shí)期吭历,以便到時(shí)執(zhí)行指定任務(wù)
  • 指定執(zhí)行任務(wù)的相對(duì)延遲時(shí)間
  • 指定重復(fù)運(yùn)行的任務(wù)

計(jì)時(shí)器要和run loop(運(yùn)行循環(huán))相關(guān)聯(lián)橙数,run loop到時(shí)候會(huì)觸發(fā)任務(wù)。創(chuàng)建NSTimer時(shí),可以將其預(yù)先安排在當(dāng)前run loop中衡招,也可以先創(chuàng)建好,然后手動(dòng)調(diào)用加入run loop中每强,它才能正常觸發(fā)任務(wù)始腾。
系統(tǒng)方法:

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval
                                     target:(id)target
                                   selector:(SEL)aSelector
                                   userInfo:(nullable id)userInfo
                                    repeats:(BOOL)repeats;

直接創(chuàng)建個(gè)實(shí)例對(duì)象,并將其加入當(dāng)前run loop當(dāng)中空执。由于計(jì)時(shí)器會(huì)保留目標(biāo)對(duì)象target浪箭,所以反復(fù)執(zhí)行任務(wù)通常會(huì)導(dǎo)致應(yīng)用程序問(wèn)題。也就是設(shè)置重復(fù)執(zhí)行模式的那種計(jì)時(shí)器辨绊,很容易引入retain cycle(保留環(huán))奶栖。

如何打破Retain Cycle

  • MSWeakTimer
  • NSTimer添加個(gè)handlerBlock

推薦MSWeakTimer

線程安全的Timer,不會(huì)對(duì)target進(jìn)行retain操作门坷,支持GCD Queue宣鄙,NSTimer的替代品MSWeakTimer現(xiàn)已支持Pod,具體實(shí)現(xiàn)及用法請(qǐng)點(diǎn)擊這里

下面主要談?wù)劦诙N默蚌,如何自己實(shí)現(xiàn)來(lái)打破retain cycle冻晤。
1.為NSTimer添加一個(gè)Category方法
NSTimer+WeakTimer.h

+ (NSTimer *)zx_scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval
                                       repeats:(BOOL)repeats
                                  handlerBlock:(void(^)())handler;

NSTimer+WeakTimer.m

+ (NSTimer *)zx_scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval
                                       repeats:(BOOL)repeats
                                  handlerBlock:(void(^)())handler
{
    return [self scheduledTimerWithTimeInterval:timeInterval
                                         target:self
                                       selector:@selector(handlerBlockInvoke:)
                                       userInfo:[handler copy]
                                        repeats:repeats];
}

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

2.如何使用這個(gè)Category方法
創(chuàng)建一個(gè)NSTimer

- (void)startPolling
{
    __weak typeof(self)weakSelf = self;
    self.timer = [NSTimer zx_scheduledTimerWithTimeInterval:5.0 repeats:YES handlerBlock:^void(void){
        __strong typeof(weakSelf)strongSelf = weakSelf;
        [strongSelf doPolling];
    }];
}

執(zhí)行輪詢?nèi)蝿?wù)slector

- (void)doPolling
{
    //Todo...;
}

銷毀NSTimer對(duì)象

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

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

計(jì)時(shí)器現(xiàn)在的targerNSTimer類對(duì)象。這段代碼先是定義了個(gè)弱引用绸吸,令其指向self,然后block捕獲這個(gè)引用鼻弧,而不直接去捕獲普通的self變量,也就是說(shuō)self不會(huì)為計(jì)時(shí)器所保留锦茁。當(dāng)block開始執(zhí)行時(shí)攘轩,立刻生成strong強(qiáng)引用,以保證實(shí)例在執(zhí)行期間持續(xù)存活码俩,不被釋放撑刺。

采用這種寫法后,外界指向NSTimer的實(shí)例最后一個(gè)引用被釋放后握玛,則創(chuàng)建NSTimer的實(shí)例也隨之被系統(tǒng)回收够傍。


Refer: Effective Objective-C 2.0 Tips52

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末甫菠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子冕屯,更是在濱河造成了極大的恐慌寂诱,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件安聘,死亡現(xiàn)場(chǎng)離奇詭異痰洒,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)浴韭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門丘喻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人念颈,你說(shuō)我怎么就攤上這事泉粉。” “怎么了榴芳?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵嗡靡,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我窟感,道長(zhǎng)讨彼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任柿祈,我火速辦了婚禮哈误,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘躏嚎。我一直安慰自己黑滴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布紧索。 她就那樣靜靜地躺著,像睡著了一般菜谣。 火紅的嫁衣襯著肌膚如雪珠漂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天尾膊,我揣著相機(jī)與錄音媳危,去河邊找鬼。 笑死冈敛,一個(gè)胖子當(dāng)著我的面吹牛待笑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播抓谴,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼暮蹂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼寞缝!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起仰泻,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤荆陆,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后集侯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體被啼,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年棠枉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浓体。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辈讶,死狀恐怖命浴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情荞估,我是刑警寧澤咳促,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站勘伺,受9級(jí)特大地震影響跪腹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜飞醉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一冲茸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧缅帘,春花似錦轴术、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至失暂,卻和暖如春彼宠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背弟塞。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工凭峡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人决记。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓摧冀,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子索昂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容