2012-08-13 58 views
0

取消目前的NSTimer我這樣做是:在NSRunLoop

timer = [NSTimer timerWithTimeInterval:timeUntilAction target:self selector:@selector(actionToPerform) userInfo:nil repeats:NO]; 
NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 
[runLoop addTimer:timer forMode:NSRunLoopCommonModes]; 

但是我想能夠無效此計時器。調用無效似乎沒有做任何事情,我不知道還有什麼要嘗試,因爲我不能從任何實例方法中刪除NSRunLoop中的定時器,我可以看到的是NSTimerNSRunLoop

我應該如何設置一個方法(actionToPerform)在經過一定的延遲(timeUntilAction)之後才能觸發,但仍然有能力在給定用戶交互的情況下取消操作。用戶還應該能夠在初始計時器(被取消的計時器)計劃關閉之前重新啓動計時器。

任何建議將是偉大的!

感謝

+2

只是踢,添加到'NSDefaultRunLoopMode'而不是'NSRunLoopCommonModes'。第二個可能會導致我的經驗意想不到的行爲(雖然,檢查文檔,我明白爲什麼現在)。 'invalidate'肯定會將它從運行循環中刪除,如果它不是,那麼你做錯了什麼。 – borrrden 2012-08-13 01:11:18

+0

@borrrden哦,天啊。你是對的。我搞砸了一個if語句。現在每個人都可能因爲沒有完全測試我的代碼而使我失望!我確信我沒有搞砸,但是我把它放在一塊太遠了。我只需要一些咖啡。謝謝! – RileyE 2012-08-13 02:22:31

+0

有人可以關閉這個問題嗎?或刪除它? – RileyE 2012-08-13 02:22:49

回答

3
[self performSelector:@selector(actionToPerform) withObject:nil afterDelay:timeUntilAction] 

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(actionToPerform) object:nil] 
+0

很酷。定時器工作,但如果你包含inRunLoop部分,這也應該工作。 – RileyE 2012-08-13 02:40:45

0

您可以在NSRunLoop取消的NSTimer。 即使您沒有在NSTimer或NSRunloop中找到API,也可以嘗試使用CFRunLoop。 根據蘋果here,怎麼看:

首先,

CFRunLoopRef *cfrl = [NSRunLoop getCFRunLoop];

然後,

CFRunLoopAddTimer

void CFRunLoopAddTimer (CFRunLoopRef rl, CFRunLoopTimerRef timer, CFStringRef mode); 

CFRunLoopRemoveTimer

void CFRunLoopRemoveTimer (CFRunLoopRef rl, CFRunLoopTimerRef timer, CFStringRef mode); 

P.S.尤其是關於

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay

看到蘋果的文檔。對於NSObject

特殊注意事項

這種方法具有其當前上下文的寄存器runloop,以及取決於runloop正在運行定期正確地執行。您可能會調用此方法並最終註冊到不會定期自動運行的runloop的一個常見上下文是由調度隊列調用的。如果在調度隊列上運行時需要此類功能,則應使用dispatch_after和相關方法來獲得所需的行爲。

此外,您可以在GitHub上使用MSWeakTimer