2014-09-30 77 views
0

我有一個應用程序每隔0.01秒記錄一些數據。當數據(NSArray)計數達到50個項目時,我想將其發送到服務器異步。問題是,當從服務器返回呼叫時,我將有另外20個地塊或更多。但另一個問題是,當它打到50時被調用的方法調用將在51,52,53等時被調用...如何防止異步方法被調用兩次?

現在我可以做的是刷新原始數組,以便下一個20當我發送原始的50個數據時,我的問題是如果數據點快速到達,在第一次調用服務器之前還有50個數據會返回?

我的問題是處理這個問題的最佳方法是什麼?也許某種異步調用工廠?所以每次我點擊50時,我都會刷新數組並將50個點發送給一些異步工廠,以創建一個知道如何發送自己的數據的異步對象?

1-50>發送到工廠,創建一個委託對象是負責發送到服務器。2-50發送到創建負責發送到服務器的委託對象的工廠。 等....

這會工作,但如果有什麼不順心的事和代表。如何協調失敗的點到服務器?是否有用於此類問題的設計模式?

+0

你如何異步發送到服務器?向我們展示一些代碼。 – 2014-09-30 18:39:09

回答

2

我認爲你的問題沒有阻止異步方法被調用了兩次。它正在安排你的任務。您正在沖洗50個物體的正確軌道上。問題是NSArray不是線程安全的對象,與多個併發方法共享相同的NSArray對象是不安全的。對於記錄數據的方法,它應該有自己的本地緩衝區。一旦本地緩衝區達到50,它將發送帶有50個對象(不是副本)的新陣列的委託回調,此時,記錄方法清除其緩衝區是安全的。

爲了您的發件人的類,它應該有一個pendingQueue陣列這是您的數據的集合,等待被髮送到服務器,你可以在這個類輕鬆處理你的錯誤。確保在pendingQueue中添加Objects或removeObject時序列化,以避免線程問題。

所以像這樣的東西應該工作。 (您將需要建立這些對象和委託一個主要方法。另外,例如省略了初始化。)

@protocol RecorderDelegate 

- (void)recorderDidReachDataPoint:(NSArray *)data; 

@end 

@interface Recorder() 

@property (nonatomic, weak) id delegate 

- (void)recordTaskWithProgressHandler 
{ 
    NSMutableArray *buffer = [NSMutableArray array]; 
    while (...pause for 0.01 second or whatever) 
    { 
     // record your task using buffer 
     // ... 
     if (buffer.count == 50) 
     { 
      if ([self.delegate respondsToSelecter:@selector(recorderDidReachDataPoint:)]) 
      { 
       [self.delegate recorderDidReachDataPoint:[NSArray arrayWithArray:buffer]]; 
      } 
      [buffer removeAllObjects]; 
     } 
    } 
} 
@end 


@interface Sender()<RecorderDelegate> 

@property (nonatomic, strong) NSMutableArray *pendingQueue; 

- (void)sendToServer 
{ 
    // Do your async method. 
    // once the data is successfully uploaded remove the object from pendingQueue 
    // if failed, you can either retry or append them to the end of pendingQueue to try later 
} 

// delegate 
- (void)recorderDidReachDataPoint:(NSArray *)data 
{ 
    [self.pendingQueue addObjectsFromArray:data]; 
    [self sendToServer]; 
} 
+0

有道理但這條線意味着什麼?同時(...暫停0.01秒或其他) – jdog 2014-09-30 19:18:08

+0

它只是意味着你想要的任何方式。我不確定你是如何每0.01秒跟蹤數據的,所以這只是一個隨機猜測。也許你可以有一個變量來停止在while循環中的跟蹤或者一個暫停0.01秒的方法,並返回true/YES甚至是別的東西。 – mosunchao 2014-09-30 21:17:17

0

我覺得處理這將是使用某種類型的隊列中的請求的最佳方式。

我可以推薦AFNetworking其是用於處理網絡請求的框架。它會檢測請求是否失敗,然後您可以再次發送。

你可以找到很多的教程和導遊如何處理與框架以及如何使用隊列請求。

+1

-1推薦ASI。甚至作者說,不要再使用它了。 – jrturton 2014-09-30 18:55:34

+0

不知道,到目前爲止它一直在爲我工作。刪除了參考。 – Exec 2014-09-30 18:58:54

+0

我試圖刪除downvote,但它不會讓我,也許是因爲你發佈後很快就編輯它。我會提交一個錯誤,但同時我會稍微編輯它,以便我可以更改我的投票 – jrturton 2014-09-30 19:18:20