【问题标题】:Waiting for a specified duration in Cocoa在 Cocoa 中等待指定的持续时间
【发布时间】:2011-01-14 23:57:54
【问题描述】:

有没有比我在下面想出的更直接的方法来在 Cocoa 中等待特定时间?

- (void) buttonPressed {
    [self makeSomeChanges];

    // give the user some visual feedback and wait a bit so he can see it
    [self displayThoseChangesToTheUser];
    [self performSelector:@selector(buttonPressedPart2:) withObject:nil afterDelay:0.35];
}

- (void) buttonPressedPart2: (id)unused {
    [self automaticallyReturnToPreviousView];
}

明确一点,这段代码没有功能问题——我唯一的缺点是风格。在我的情况下,流程很简单,它可以工作,但尝试封装它或加入一些条件,事情可能会变得丑陋。有点烦我,我找不到等待的方法,然后在像这样(虚构)示例的代码中返回同一点:

- (void) buttonPressed {
    [self doStuff];
    [UIMagicUnicorn waitForDuration:0.35];
    [self doStuffAfterWaiting];
}

【问题讨论】:

标签: objective-c cocoa wait


【解决方案1】:

有

usleep(1000000);

和

[NSThread sleepForTimeInterval:1.0f];

两者都会休眠 1 秒。

【讨论】:

  • 两者都会阻止线程做任何其他事情。不好,如果它在主 UI 中线程。
  • 是的。如果您需要 UI 在此期间做出响应,则问题中建议的方法、NSTimer 触发一次(如您建议的那样)或执行此延迟的后台线程会更好。
  • 谢谢——这就是我想知道的,如果“睡眠”是我想搜索的“等待”的几个同义词之一,可能会偶然发现它。也感谢 Pestilence 关于何时不使用这些的警告。
  • 使用带有块的 RunAfterDelay 的方法不会阻塞你的主线程。
【解决方案2】:

这是 NSTimer 的做法。它可能比您使用的方法更丑陋,但它允许重复事件,所以我更喜欢它。

[NSTimer scheduledTimerWithTimeInterval:0.5f 
                                 target:self
                               selector: @selector(doSomething:) 
                               userInfo:nil
                                repeats:NO];

您要避免使用类似 usleep() 的东西,它只会挂起您的应用并使其感觉无响应。

【讨论】:

  • "You want to avoid something like usleep() which will just hang your app and make it feel unresponsive." 可以肯定的是,只有当您从主线程调用 usleep 时,这才是正确的。
【解决方案3】:

我不确定它是否存在(还存在),但是对于 10.6 中的块(或 10.5 和 iPhone 上的 PLBlocks),编写像 performBlock:afterDelay: 这样的小包装器应该很容易,它的作用正是你想要不需要睡眠整个线程。确实是一段有用的小代码。

Mike Ash 有written about an approach like this on his blog:

NSString *something = ...;
RunAfterDelay(0, ^{
    NSLog(@"%@", something);
    [self doWorkWithSomething: something];
});

【讨论】:

  • 或者只使用NSTimer的scheduledTimerWithTimeInterval:repeats:block:
  • 可能在 10.6 中不存在……不记得了
【解决方案4】:

简单的usleep 有什么问题?我的意思是,除了“可可纯度”之外,它仍然比其他解决方案短得多:)

【讨论】:

  • 它阻塞了线程。如果在 main 中调用它,您实际上是在终止运行循环,并且应用程序将显示为“死”
  • 那就不要从main调用
【解决方案5】:

您可能希望使用NSTimer 并让它发送“doStuffAfterWaiting”消息作为您的回调。任何类型的“睡眠”都会阻塞线程,直到它醒来。如果它在你的 U.I.线程,它会导致您的应用程序出现“死机”。即使不是这样,也是不好的形式。回调方法将释放 CPU 以执行其他任务,直到达到您指定的时间间隔。

doc 提供了一些用法示例,并讨论了创建计时器的方式和位置的差异。

当然,performSelector:afterDelay: 做同样的事情。

【讨论】:

    【解决方案6】:

    如果您不介意异步解决方案,可以使用:

    [[NSOperationQueue currentQueue] addOperationWithBlock:^{
        [self doStuffAfterWaiting];
    }];
    

    【讨论】:

      【解决方案7】:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多