2011-07-19 82 views
10

我有一個NSTimer,我這個代碼初始化:的NSTimer不點火

testTimer = [[NSTimer alloc] initWithFireDate:[new objectAtIndex:0] interval:0.0 target:self selector:@selector(works:) userInfo:nil repeats:NO]; 

[new objectAtIndex:0]是過去一個NSDate。

當我啓動應用程序時,定時器正在創建,立即(因爲日期在過去)的fireDate,但它永遠不會調用我的工作方法。 (-(void)works:(id)sender

有人知道爲什麼會發生這種情況嗎?

+0

是否是錯誤的使用iphone標籤在這個問題? – Aravindhan

+6

這是一個mac應用程序。 –

+1

馬特,你可以使用[osx]標籤來幫助抵擋iOS的零售商。 :) –

回答

18

如果使用initWith..方法創建計時器對象,則必須將其添加到當前運行循環中。

NSRunLoop * theRunLoop = [NSRunLoop currentRunLoop]; 
[theRunLoop addTimer:testTimer forMode:NSDefaultRunLoopMode]; 

或者如果您希望爲您設置,請使用scheduled...方法創建您的計時器。

+0

是的,就是這樣。 –

+4

@Matt:應該指出,使用'alloc' /'init'意味着你擁有這個定時器並且需要管理它的內存,而'scheduledTimer ...'方法返回一個你不擁有的定時器。在任何一種情況下,都由運行循環保留。 –

+0

@josh感謝您的信息! –

14

我剛剛在NSTimer中遇到了問題。在我的情況下,我沒有意識到scheduledTimerWithTimeInterval方法不是多線程安全的。一旦我將計時器移至主線程,它就開始工作。

+1

請問您是怎麼​​做到的?我有一個問題,看似隨機發射。 –

+5

嘗試將nstimer包裝在此:dispatch_async(dispatch_get_main_queue(),^ { }); – Dobler

1

我想我和Dobler有同樣的問題,但是我的解決方案是不同的。

的問題是,計時器被創建和安排在GCD線程塊中的

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{}) 

調用內(實際上嵌套深,所以並不明顯,這是這種情況)。

使用NSTimer's scheduledTimerWithTimeInterval:...將計時器置於無效運行循環中。

定盤更改爲

timer = [NSTimer timerWithTimeInterval:1.0f target:self selector:@selector(...) userInfo:nil repeats:YES]; 
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];