定时 UIAlert 每 60 秒触发一次,无论我使用啥延迟

Posted

技术标签:

【中文标题】定时 UIAlert 每 60 秒触发一次,无论我使用啥延迟【英文标题】:Timed UIAlert Fires every 60s No Matter What delay I Use定时 UIAlert 每 60 秒触发一次,无论我使用什么延迟 【发布时间】:2012-12-20 13:54:28 【问题描述】:

我想在用户使用该应用一小时后显示警报

在应用委托中:

首先我尝试了这个:Displaying UIAlertView after some time

然后我尝试了

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

[self performSelector:@selector(showAlert) withObject:nil afterDelay:3600];

return YES;


-(void)showAlert
  UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"title!"
                                                 message:@"message!"
                                                delegate:self
                                       cancelButtonTitle:@"Cancel"
                                       otherButtonTitles:nil];
  [alert show];

在这两个示例中,我都尝试使用after delay 中的各种数字。无论我为延迟添加什么,计时器每次都会在一分钟后触发?

更新: 这是正确的代码,除了委托之外,我还将它留在了视图控制器的 viewDidLoad 中,因此它也在触发该方法。谢谢大家

【问题讨论】:

您的示例代码都是同一个方法的一部分吗?如果@selector() 是调用另一个方法,包含接下来的两行代码,它应该可以工作。请添加其他代码以进行说明。 您是否考虑过使用通知来处理此计时器?将开火日期设置为未来 60 分钟,然后在通知部分处理您的操作/警报?如果应用未处于活动状态,您可以忽略通知或在应用关闭时将其删除。 已编辑以显示更多代码,这实际上是作为测试应用程序的所有代码,没有其他任何更改我所做的只是将上述方法添加到代表 didfifnshlaunching 感谢所有更新的问题来解释为什么它不起作用。 【参考方案1】:

如果你这样做:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions


    [self performSelector:@selector(showAlert) withObject:nil afterDelay:3600];

    return YES;


-(void)showAlert
    UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"title!"
                                                     message:@"message!"
                                                    delegate:self
                                           cancelButtonTitle:@"Cancel"
                                           otherButtonTitles:nil];
    [alert show];

你应该编辑你的问题,并添加额外的信息,因为问题必须在其他地方。

否则,这就是你的答案。

【讨论】:

感谢您的回复,它确认我编码正确,然后在搜索时发现 id 在 vi​​ewDidLoad 中留下了这个方法。标记为正确,因为您的编码正确并引导我找到答案【参考方案2】:

您的代码应该可以工作您确定您没有在其他地方调用showAlert 吗? 你也可以试试这个,只是为了确保:

  long long int anHourInNanoSec = 60*60*NSEC_PER_SEC;
  long long int anHourFromNow = dispatch_time(DISPATCH_TIME_NOW, anHourInNanoSec);

  dispatch_after(anHourFromNow, dispatch_get_current_queue(), ^
            [self showAlert];
        );

顺便说一句,如果应用程序使用一个小时,我不确定你的方法是否会启动。如果应用程序设置为后台,您应该停止计时器。

【讨论】:

您好,感谢您的回复,是的,这正是您的回答到来之前发生的事情!这很好,当它进入后台时,关于该方法的任何提示/代码?为您提供一个有用的信息! 我的第一个想法是在启动时存储剩余时间。然后创建一个“守护程序”,当计时器耗尽时将触发警报。守护进程可能每 1 或 5 秒减少一次剩余时间,然后进入睡眠状态;并在剩余时间小于或等于 0 时触发警报。这样做,您只需在应用程序进入后台模式时停止守护程序,并在应用程序返回前台时重新激活它。【参考方案3】:

对不起,新的答案,但评论字段太短,你可以试试这样的:

... .h

@property (nonatomic, assign) long long int remainingTime; @property (nonatomic, assign) BOOL deamonPaused;

... .m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 

   long long int anHourInNanoSec = 60*60*NSEC_PER_SEC;
   _remainingTime = dispatch_time(DISPATCH_TIME_NOW, anHourInNanoSec);
   _deamonPaused = NO;

   dispatch_queue_t deamonThread = dispatch_queue_create(@"deamonThread", NULL);
   dispatch_async(deamonThread, ^
            [self launchDeamon];
        );
    dispatch_release(deamonThread);

    return YES; 


- (void) launchDeamon
   while (_remainingTime > 0)
      if (!_deamonPaused)
         _remainingTime -= 5*NSEC_PER_SEC; 
      sleep(5);
   
   [self showAlert];


- (void) applicationDidEnterBackground:(UIApplication *)application
    _deamonPaused = YES; 


- (void) applicationWillEnterForeground:(UIApplication *)application
   _deamonPaused = NO;

【讨论】:

谢谢 Citron,我要试试看!再给我加 1!

以上是关于定时 UIAlert 每 60 秒触发一次,无论我使用啥延迟的主要内容,如果未能解决你的问题,请参考以下文章

python定时器每隔几秒执行一次

本地通知每 30 秒重复一次

spring quartz 定时器时间格式设置

JavaScript定时器案例:显示年月日时分秒+每隔60s发送一次短信

quartz 一次触发执行多次job

定时器完成后重启功能