我有一个应用程序,每隔0.10秒跟踪一些数据。当数据(NSArray)计数达到50项时,我想以异步方式将其发送到服务器。问题是,当呼叫从服务器返回时,我将有另外20个或更多的情节。但另一个问题是当它达到50时被调用的方法调用将在其51,52,53等时被调用...
现在我可以做的是刷新原始数组,以便在我发送原始数据50时进入下一个数组,但我的问题是如果数据点快速到达我会在第一次调用之前得到50以上服务器返回?
我的问题是处理这个问题的最佳方法是什么?也许是某种异步调用工厂?因此,每次达到50时,我都会刷新阵列并将50点发送到某个异步工厂,该工厂会创建一个知道如何发送自己数据的异步对象?
1-50>发送到工厂,创建一个负责发送到服务器的委托对象。 2-50发送到工厂,创建一个委托对象,负责发送到服务器。 等....
这可行,但如果出现问题并在代表中会怎样。如何协调未能成功的点到服务器?是否有用于此类问题的设计模式?
答案 0 :(得分:2)
我认为你的问题不是阻止异步方法被调用两次。它安排你的任务。在冲洗50个物体时你正走在正确的轨道上。问题是NSArray不是一个线程安全的对象,与多个并发方法共享同一个NSArray对象是不安全的。对于记录数据的方法,它应该有自己的本地缓冲区。一旦本地缓冲区达到50,它就会发送一个带有50个对象(不是副本)的新数组的委托回调,此时,记录方法可以安全地清除它的缓冲区。
对于你的Sender类,它应该有一个pendingQueue数组,它是等待发送到服务器的数据集合,你可以轻松地在这个类中处理你的错误。确保在pendingQueue中添加对象或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];
}
答案 1 :(得分:0)
我认为处理此问题的最佳方法是为请求使用某种队列。
我可以推荐AFNetworking这是一个处理网络请求的框架。它将检测请求是否失败,您可以再次发送。
您可以找到许多教程和指南,了解如何使用框架处理请求以及如何使用队列。