2014-09-30 60 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