2012-07-16 56 views
0

我試圖連接到給定IP地址上的端口。一個問題是,當建立了與不存在的IP的連接地址的寫入命令(這是如下):NSTimer未及時觸發

NSData * imageRequest = [@"640" dataUsingEncoding: NSUTF8StringEncoding]; 

int image = [self.outputImageStream write:[imageRequest bytes] maxLength:[imageRequest length]]; 

這需要超過75秒,以進行響應。我嘗試處理這個通過啓動一個定時器,具有以下的方法調用:

self.connectionTimeoutTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(respondToTimer:)userInfo:nil repeats:NO]; 

它不是1秒間隔I定義中調用。

有沒有什麼辦法可以確保定時器在1秒內發射?

+0

我認爲這篇博文可能會回答你的一些問題:http:// atastypixel。com/blog/experimental-with-precise-timing-in-ios/ – 2012-07-16 14:28:02

+2

嘗試使用dispatch_after而不是 – Felix 2012-07-16 14:30:07

+0

調用多長時間後? – 2012-07-16 14:33:41

回答

1

這可能會回答你的問題有關NSTimer real-time behavior

計時器不是實時的機制;只有在添加了定時器的運行循環模式之一運行並且能夠檢查定時器的觸發時間是否已過時,它纔會觸發。由於典型的運行循環管理各種輸入源,所以定時器的時間間隔的有效分辨率被限制在50-100毫秒的量級上。如果在長時間標註期間發生定時器的觸發時間,或者運行循環處於未監視定時器的模式下,定時器將在下次運行循環檢查定時器時才觸發。因此,計時器觸發的實際時間可能是計劃的點火時間之後的相當長的一段時間。

你不指定要如何調度的NSTimer,但如果你將其排定的NSRunLoopCommonModes代替NSRunLoopDefaultModes你可能會發現其性能有所改善:

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 

如果不能改善的事情,那麼你應該尋找更低層次的選擇。

特別是,你可能會考慮CADisplayLink

一個CADisplayLink對象是一個計時器對象,它允許您的應用程序其繪圖同步到顯示器的刷新速率。

它可以以與NSTimer非常相似的方式使用。

CADisplayLink的優點是鏈接到刷新率,所以它應該在1/60秒的時間間隔內提供非常可靠的行爲。

使用CADisplayLink的示例:

CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(respondToTimer)]; 
[displayLink setFrameInterval:60]; 
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; 

這將調用respondTimer各60個刷新幀,即,每秒一次。既然你想讓你的方法只被稱爲一個,你可以使用:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), 
          dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
           [self respondToTimer]; 
          }); 

它可能會更容易爲你。 (當然,您可以用該方法的完整實現來替換對[self respondToTimer]的調用)。

+0

我將如何使用CADisplayLink?我是Objective C的新手,所以我對如何實現這一點感到困惑。謝謝你回答這個! – 2012-07-16 20:02:36

+0

嘿塞爾吉奧。我按照你的說法實現了它,但它仍然沒有被調用,所以還有其他想法? – 2012-07-17 12:57:56

+0

你的'respondToTimer'方法在某個時候被調用了嗎?這只是一個問題,沒有在正確的時間被呼叫,或者根本沒有被呼叫?你有沒有試過dispatch_after? – sergio 2012-07-18 07:19:04