如何防止异步方法表单被调用两次?

时间:2014-09-30 17:31:29

标签: ios objective-c asynchronous

我有一个应用程序,每隔0.10秒跟踪一些数据。当数据(NSArray)计数达到50项时,我想以异步方式将其发送到服务器。问题是,当呼叫从服务器返回时,我将有另外20个或更多的情节。但另一个问题是当它达到50时被调用的方法调用将在其51,52,53等时被调用...

现在我可以做的是刷新原始数组,以便在我发送原始数据50时进入下一个数组,但我的问题是如果数据点快速到达我会在第一次调用之前得到50以上服务器返回?

我的问题是处理这个问题的最佳方法是什么?也许是某种异步调用工厂?因此,每次达到50时,我都会刷新阵列并将50点发送到某个异步工厂,该工厂会创建一个知道如何发送自己数据的异步对象?

1-50>发送到工厂,创建一个负责发送到服务器的委托对象。 2-50发送到工厂,创建一个委托对象,负责发送到服务器。 等....

这可行,但如果出现问题并在代表中会怎样。如何协调未能成功的点到服务器?是否有用于此类问题的设计模式?

2 个答案:

答案 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这是一个处理网络请求的框架。它将检测请求是否失败,您可以再次发送。

您可以找到许多教程和指南,了解如何使用框架处理请求以及如何使用队列。