Objective-C - 两种异步方法,等待条件

时间:2012-12-01 18:20:15

标签: objective-c ios cocoa asynchronous wait

我正在运行两个异步方法(请参阅此SO thread以供参考)。

除非我有这种情况,否则它的工作非常完美。当在任一方法中发生错误时,我将为用户显示此信息,因此在块中我将检查错误并执行此操作:

if(error) {
    int64_t delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), {

    // Show a popup for 2.0 seconds alerting the user of the error
    });
}

这没有问题。但是,当两者这些异步操作都有错误时,就会出现问题。完成的第一个方法将显示错误,可能只需0.5秒,然后第二个异步操作将显示错误2.0秒(不考虑已显示错误消息)。

所以我需要一些进程来检查是否已经显示错误消息,然后等待该错误消息消失(2.0秒),然后立即显示第二条错误消息。

2 个答案:

答案 0 :(得分:2)

听起来你只需要实现一个队列来向用户显示这些错误。您可以在SSHUDView上将其作为一个类别,使用这样的简单界面:

@interface SSHUDView (queue)
- (void)showForDuration:(NSTimeInterval)duration;
@end

使用串行GCD队列实现它:

@implementation SSHUDView (queue)

- (void)showForDuration:(NSTimeInterval)duration {
    static dispatch_once_t once;
    static dispatch_queue_t queue;
    dispatch_once(&once, ^{
         queue = dispatch_queue_create("SSHUDView(serial)", 0);
    });

    dispatch_async(queue, ^{
        dispatch_sync(dispatch_get_main_queue(), ^{
            [self show];
        });

        usleep(duration * USEC_PER_SEC);

        dispatch_sync(dispatch_get_main_queue(), ^{
            [self dismiss];
        });
    });
}

@end

答案 1 :(得分:1)

作为Rob Mayoff的良好答案的替代方案,您可能希望改为重构UI。一个接一个地弹出对话框对你和最终用户来说都有点乏味。事实上,弹出对话框可能会很乏味,特别是如果它们是模态的(甚至只是作为表格)。

也许你可以做一些更有趣的事情?就像让错误显示为从窗口顶部向下滑动的横幅一样。如果您有多个错误,您只有多个横幅,一个低于另一个。然后他们会在适当的时间淡出(虽然小心自动解雇,因为用户可能不会一直看着你的应用程序)。

另一种方法是使用一个对话框,但在发生其他错误时更改或附加到其消息。这有一个缺点,即用户在阅读时可能会改变对话框,所以你必须小心谨慎并仔细考虑这是否合适。它在错误密切相关的情况下非常有用,例如:您尝试连接到您的服务器,但它失败了。因此,在启动常规网络连接测试的同时显示错误消息。当该测试返回并说网络完全消失时,您更新对话框以澄清它不是服务器停机而是您的互联网连接。

或者,如果您以与音量变化指示器相同的方式显示这些叠加层,您可能只想并排显示它们。你甚至可以想象并让现有的一个(或者)向左滑动以为新的滑动腾出空间,但除非它们是非常简单的图标,否则可能会让用户难以理解正在发生的事情。