我如何使用 NSTimer(或其他)使事件在 Cocoa 中的特定时间之后发生?

发布于 2024-12-19 15:07:18 字数 1101 浏览 4 评论 0原文

我正在使用 Xcode 创建一个用 Objective-C 编写的 Mac OSX Cocoa 应用程序。

这是我的代码:

-(IBAction)clickToLaunchAppButtonClicked:(id)sender; {
//I want to hide the click to load app button
[clickToLoadButton setEnabled:NO];
[clickToLoadButton setHidden:YES];

//***I want to make the app wait for 1 second (This is where I'm stuck!)***

//I want to show the loading label
[loadingLabel setEnabled:YES];
[loadingLabel setHidden:NO];

//I want to show the loading progress bar and initialize it
[loadingProgressBar setHidden:NO];
[loadingProgressBar startAnimation:self];

//***I want to make the app wait for 3 seconds (Again, I don't know how to do this!)***

//I want to stop the loading progress bar animation
[loadingProgressBar stopAnimation:self];

//I want to hide the loading progress bar and loading label
[loadingLabel setHidden:YES];
[loadingLabel setEnabled:NO];
[loadingLabel setHidden:YES];
}

如何让应用程序等待/暂停几秒钟?我尝试了 wait()delay()pause() 函数,但它们冻结了应用程序,这不是我想要的。我应该使用 NSTimer 吗?如果是这样,请给我一个简单的实现方法。

I am using Xcode to create a Cocoa app for Mac OSX written in Objective-C.

Here is my code:

-(IBAction)clickToLaunchAppButtonClicked:(id)sender; {
//I want to hide the click to load app button
[clickToLoadButton setEnabled:NO];
[clickToLoadButton setHidden:YES];

//***I want to make the app wait for 1 second (This is where I'm stuck!)***

//I want to show the loading label
[loadingLabel setEnabled:YES];
[loadingLabel setHidden:NO];

//I want to show the loading progress bar and initialize it
[loadingProgressBar setHidden:NO];
[loadingProgressBar startAnimation:self];

//***I want to make the app wait for 3 seconds (Again, I don't know how to do this!)***

//I want to stop the loading progress bar animation
[loadingProgressBar stopAnimation:self];

//I want to hide the loading progress bar and loading label
[loadingLabel setHidden:YES];
[loadingLabel setEnabled:NO];
[loadingLabel setHidden:YES];
}

How can I make the app wait/pause for a few seconds? I tried the wait(), delay() or pause() functions, but they freeze the app, which is not what I want. Should I use an NSTimer? If so, please give me a simple way to implement it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不交电费瞎发啥光 2024-12-26 15:07:19

我建议改用新的 Grand Central Dispatch API。

例如:

-(IBAction)clickToLaunchAppButtonClicked:(id)sender {
  //I want to hide the click to load app button
  [clickToLoadButton setEnabled:NO];
  [clickToLoadButton setHidden:YES];

  // wait one second
  dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC);
  dispatch_after(popTime, dispatch_get_main_queue(), ^{

    //I want to show the loading label
    [loadingLabel setEnabled:YES];
    [loadingLabel setHidden:NO];

    //I want to show the loading progress bar and initialize it
    [loadingProgressBar setHidden:NO];
    [loadingProgressBar startAnimation:self];

    // execute the rest after 3 seconds
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 3.0 * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^{

      //I want to stop the loading progress bar animation
      [loadingProgressBar stopAnimation:self];

      //I want to hide the loading progress bar and loading label
      [loadingLabel setHidden:YES];
      [loadingLabel setEnabled:NO];
      [loadingLabel setHidden:YES];
    });
  });
}

有三个优点:

  • 代码更少,更干净。您无需定义额外的方法,所有代码都位于一处。
  • GCD api 的速度快得令人难以置信,尽管在您的示例中它可能并不重要,有时这很重要,尤其是在 iPhone 上,其中“快速”也意味着“更长的电池寿命”
  • 要执行的代码与代码共享范围这就是所谓的。外部代码中的任何变量都可以在稍后执行的代码中使用

I recommend using the new Grand Central Dispatch API instead.

For example:

-(IBAction)clickToLaunchAppButtonClicked:(id)sender {
  //I want to hide the click to load app button
  [clickToLoadButton setEnabled:NO];
  [clickToLoadButton setHidden:YES];

  // wait one second
  dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC);
  dispatch_after(popTime, dispatch_get_main_queue(), ^{

    //I want to show the loading label
    [loadingLabel setEnabled:YES];
    [loadingLabel setHidden:NO];

    //I want to show the loading progress bar and initialize it
    [loadingProgressBar setHidden:NO];
    [loadingProgressBar startAnimation:self];

    // execute the rest after 3 seconds
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 3.0 * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^{

      //I want to stop the loading progress bar animation
      [loadingProgressBar stopAnimation:self];

      //I want to hide the loading progress bar and loading label
      [loadingLabel setHidden:YES];
      [loadingLabel setEnabled:NO];
      [loadingLabel setHidden:YES];
    });
  });
}

There are three advantages:

  • It's less code, and cleaner. You don't need to define extra methods and all your code is in one place.
  • The GCD api is increadibly fast, though in your example it probably doesn't matter much, sometimes this is important, especially on an iPhone where "fast" also means "longer battery life"
  • The code to be executed shares the scope with the code that calls it. Any variables in the outer code, are available in the code to be executed later
灼疼热情 2024-12-26 15:07:19

您可以将要在 3 秒延迟上运行的代码放在另一个方法 (delayedLoad) 中,并使用 performSelector: withObject: afterDelay:

[self performSelector:@selector(delayedLoad) withObject:nil afterDelay:3.0];

编辑 - 详细拼写以响应您的评论

以创建另一个方法,将此代码包含在同一个 .m 文件(AppDelegate.m 或类似文件)中

-(void)delayedLoad
{

//I want to stop the loading progress bar animation
[loadingProgressBar stopAnimation:self];

//I want to hide the loading progress bar and loading label
[loadingLabel setHidden:YES];
[loadingLabel setEnabled:NO];
[loadingLabel setHidden:YES];
}

,并且您现有的方法将变为

-(IBAction)clickToLaunchAppButtonClicked:(id)sender; {
//I want to hide the click to load app button
[clickToLoadButton setEnabled:NO];
[clickToLoadButton setHidden:YES];

//***I want to make the app wait for 1 second (This is where I'm stuck!)***

//I want to show the loading label
[loadingLabel setEnabled:YES];
[loadingLabel setHidden:NO];

//I want to show the loading progress bar and initialize it
[loadingProgressBar setHidden:NO];
[loadingProgressBar startAnimation:self];
[self performSelector:@selector(delayedLoad) withObject:nil afterDelay:3.0];
}

这就是您实现 3 秒延迟的方式。希望你可以扩展它以实现 1 秒延迟

You can place the code you want to run on the 3 second delay in another method (delayedLoad) and use performSelector: withObject: afterDelay:

[self performSelector:@selector(delayedLoad) withObject:nil afterDelay:3.0];

EDIT - spelling it out more in response to your comment

to create the other method, include this code in the same .m file (AppDelegate.m or similar)

-(void)delayedLoad
{

//I want to stop the loading progress bar animation
[loadingProgressBar stopAnimation:self];

//I want to hide the loading progress bar and loading label
[loadingLabel setHidden:YES];
[loadingLabel setEnabled:NO];
[loadingLabel setHidden:YES];
}

And your existing method becomes

-(IBAction)clickToLaunchAppButtonClicked:(id)sender; {
//I want to hide the click to load app button
[clickToLoadButton setEnabled:NO];
[clickToLoadButton setHidden:YES];

//***I want to make the app wait for 1 second (This is where I'm stuck!)***

//I want to show the loading label
[loadingLabel setEnabled:YES];
[loadingLabel setHidden:NO];

//I want to show the loading progress bar and initialize it
[loadingProgressBar setHidden:NO];
[loadingProgressBar startAnimation:self];
[self performSelector:@selector(delayedLoad) withObject:nil afterDelay:3.0];
}

This is how you implement the 3 second delay. Hopefully you can extend this to implement the 1 second delay

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文