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

标签 ios objective-c asynchronous

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

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

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

1-50 > 发送到工厂,该工厂创建负责发送到服务器的委托(delegate)对象。 2-50 发送到创建负责发送到服务器的委托(delegate)对象的工厂。 等等……

这会起作用,但如果在委托(delegate)中出现问题怎么办。如何协调未能到达服务器的点?是否有用于此类问题的设计模式?

最佳答案

我认为你的问题不是阻止异步方法被调用两次。它正在安排您的任务。您在刷新 50 个对象方面走在正确的轨道上。问题是 NSArray 不是线程安全对象,多个并发方法共享同一个 NSArray 对象是不安全的。对于记录数据的方法,它应该有自己的本地缓冲区。一旦本地缓冲区达到 50,它就会向委托(delegate)回调发送一个包含 50 个对象的新数组(不是副本),此时,记录方法可以安全地清除其缓冲区。

对于您的 Sender 类,它应该有一个 pendingQueue 数组,它是您等待发送到服务器的数据的集合,您可以轻松地处理此类中的错误。确保在 pendingQueue 中添加对象或删除对象时进行序列化以避免线程问题。

所以像这样的东西应该可以工作。 (您将需要一个主要方法来设置这些对象和委托(delegate)。此外,该示例省略了初始化。)

@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];
}

关于ios - 如何防止异步方法表单被调用两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26126715/

相关文章:

objective-c - iOS 在 View 之间传递消息,基于窗口的应用程序

ios - 在 iOS 7 上以编程方式安装 .mobileconfig 文件

java - 当 CompleteableFuture 既没有完成、取消也没有异常时,会发生什么?

ios - Xcode 6.1.1 中没有空的项目部分?

iphone - 我目前在控制台 : 中收到此崩溃日志

ios - 如何通过 Swift 使用 Base64Url 编码 json 对象,如 JWT header 和有效负载

iOS 7 View 布局和半透明效果

objective-c - 无法找到我的错误 'expected method body' 错误

javascript - 如何使用 bluebird 正确地 promise JSON.parse 方法

c# - 等待/异步奇怪的行为