如何在计算机睡着或用户注销时触发 NSTimer

Posted

技术标签:

【中文标题】如何在计算机睡着或用户注销时触发 NSTimer【英文标题】:How to fire NSTimer when computer is asleep or user is logged out 【发布时间】:2020-09-20 19:28:01 【问题描述】:

我想在 6 小时后触发计时器。但由于我的电脑处于睡眠模式,定时器在 6 小时后没有触发。我在 6 个多小时后登录计算机后 2 分钟触发它。即使用户处于注销或系统睡眠模式,是否可以触发计时器?

【问题讨论】:

您可以通过IOPMSchedulePowerEvent 安排机器从睡眠中唤醒、开机、进入睡眠或关机。它还取决于它是否是 MacBook Pro,因为 IIRC 如果盖子关闭,您将无法执行此操作。 您可以查看Fermata - Fermata 是一个小型 macOS 实用程序,可在某些情况下防止盖子关闭睡眠。 您可以阻止您的 Mac 与 NSActivityOptions 等一起睡觉。您的问题太笼统了,很难提供帮助。尝试使用我提供给您的信息,然后返回对您不起作用的代码,并对您要实现的目标进行更高级别的解释。 如果您根本不想阻止计算机进入睡眠状态,您可以设置计时器启动时间的时间戳,当计算机被唤醒时,立即运行预定的方法。见didWakeNotification:developer.apple.com/documentation/appkit/nsworkspace/… 这能回答你的问题吗? NSTimer continue during sleep mode 【参考方案1】:

这是一种简单的方法。为即将发生的事件创建一个NSDate,并设置一个计时器来比较当前时间和该时间戳。此示例每秒运行一次。

- (void) waitFor:(CGFloat)seconds 
    // Set the time to wait
    NSTimeInterval timeInSeconds = seconds; 
    __block NSDate *wait = [[NSDate date] dateByAddingTimeInterval:timeInSeconds];

    [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) 
        NSDate *time = [NSDate date];
        if ([time timeIntervalSinceDate:wait] > 0) 
            // Do something
        
    ];

这样,唤醒您的计算机后该进程将立即运行。

编辑:较早的线程(例如NSTimer continue during sleep mode)建议您在唤醒后需要重新安排NSTimer,但现在似乎不再如此了。

【讨论】:

以上是关于如何在计算机睡着或用户注销时触发 NSTimer的主要内容,如果未能解决你的问题,请参考以下文章

Spring security logout - 仅在登录用户触发注销时添加消息

当 runloop 被阻塞时,NSTimer 不会触发

睡眠后可可 NSTimer

如何在用户从帐户注销时断开事件触发(node.js + express socket.io)

当用户关闭浏览器或选项卡而不注销时如何将用户标记为离线

发生 uiscrollview 事件时未触发 NSTimer