開始前咱們先知道NSTimer是用來的干嘛的。
A timer waits until a certain time interval has elapsed and then fires,
sending a specified message to a target object.
從這里我們可以看出來监嗜,NSTimer就是我為了過一段時(shí)間想目標(biāo)發(fā)送一個(gè)消息毕泌,從而執(zhí)行一系列的操作。既然我們已經(jīng)知道用法纯趋。所以咱們先來個(gè)最簡(jiǎn)單的用法
[NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(run:) userInfo:nil repeats:YES];
方法實(shí)現(xiàn)里直接打印helloworld就好憎兽,這里我就不再占用篇幅去寫了。自己去補(bǔ)就好吵冒。上面這個(gè)函數(shù)的意思就是每隔1.5秒執(zhí)行一次run方法纯命。注意:如果repeats參數(shù)為NO時(shí),只會(huì)執(zhí)行一遍該方法痹栖。
接下來我們看看怎樣控制定時(shí)器的開關(guān)
[_timer setFireDate:[NSDate distantFuture]];
調(diào)用上面語句亿汞,定時(shí)器就會(huì)關(guān)閉
[_timer setFireDate:[NSDate distantPast]];
上面就是開啟定時(shí)器
關(guān)于NSTimer也不能說的太深,因?yàn)闋可娴揭恍﹔unloop的知識(shí)揪阿。大家有興趣的可以去研究一下疗我。我也做過這方面的研究咆畏,只可惜研究尚欠,難等大雅之堂吴裤,今天就不跟大家分享旧找,等我研究的小有成就的時(shí)候。在跟大家分享嚼摩。
今天我在做AVPlayer的自定義過程中有要用到定時(shí)器,其中就涉及到runloop矿瘦,今天我跟新博文不為談runloop的底層實(shí)現(xiàn)枕面,只為談涉及到NSTimer一些bug的解決方案;
問題假設(shè)缚去,我們需要程序定時(shí)做一件事潮秘,這個(gè)時(shí)候我們創(chuàng)建NSTimer
_timer = [NSTimer timerWithTimeInterval:1.5 target:self selector:@selector(nslog) userInfo:nil repeats:YES];
細(xì)心的同學(xué)會(huì)發(fā)現(xiàn),這個(gè)NSTimer不會(huì)被執(zhí)行易结,即使我們調(diào)用上面的開啟方法枕荞,也不會(huì)執(zhí)行。下面跟大家簡(jiǎn)單談一下NSTimer的底層實(shí)現(xiàn)搞动。
當(dāng)我們創(chuàng)建NSTimer后躏精,只有將NSTimer放到一個(gè)事件循環(huán)鏈(eventloop)中,NSTimer才能一直執(zhí)行下去鹦肿,iOS中我們實(shí)現(xiàn)的方法就是放到runloop中矗烛。所以我們想要讓上面創(chuàng)建的NSTimer執(zhí)行,我們就必須將NSTimer放到一個(gè)runloop鐘箩溃。我的解決方案是獲取當(dāng)前的runloop瞭吃,然后將NSTimer放進(jìn)去。代碼如下
NSRunLoop *run = [NSRunLoop currentRunLoop];
[run addTimer:_timer forMode:NSRunLoopCommonModes];
或許大家會(huì)問為什么用第一個(gè)方法創(chuàng)建時(shí)能夠直接執(zhí)行那涣旨,我跟人的推測(cè)歪架,應(yīng)該運(yùn)用schedul創(chuàng)建的NSTimer,默認(rèn)會(huì)將當(dāng)前創(chuàng)建的NSTimer放到當(dāng)前的runloop中霹陡。
文章的最后我們說一下NSTimer的內(nèi)存釋放問題和蚪。因?yàn)镹STimer是需要加入runloop中,這就形成了一個(gè)典型的循環(huán)引用烹棉,所以我們必須顯示的釋放掉NSTimer惠呼,否則就會(huì)造成內(nèi)存泄漏。
特別強(qiáng)調(diào):
NSTimer的釋放不能放到dealloc中進(jìn)行峦耘,試問上面兩個(gè)哥們沒有停止剔蹋,dealloc怎么執(zhí)行。所以這里一定要注意辅髓,不能講NSTimer放到dealloc中釋放泣崩。至于在哪釋放少梁,根據(jù)自己需要的去釋放就好了。
[_timer invalidate];
_timer = nil;