4

kIOPMAssertionTypeNoIdleSleepkIOPMAssertionTypePreventSystemSleep和有什么区别kIOPMAssertionTypePreventUserIdleSystemSleep

我正在尝试创建一个IOPMAssertion可以防止 mac 自动进入睡眠状态的功能,但我真的不知道应该使用哪一个。我对他们的描述感到困惑,无法理解它们(请参阅文档)。

如果你很好奇,这就是我在代码中的做法:

IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, CFSTR("My app is running"), &preventSleepAssertionID);

if (success != kIOReturnSuccess) {
    NSLog(@"Could not create sleep prevention assertion");
}
4

2 回答 2

1

苹果已经发布了关于这个主题的问答笔记,我相信它回答了你的问题。有问题的示例代码中的关键注释:

// kIOPMAssertionTypeNoDisplaySleep prevents display sleep,
// kIOPMAssertionTypeNoIdleSleep prevents idle sleep

前者可防止屏幕变暗或完全关闭。如果您的应用程序将以用户不使用键盘和鼠标的方式使用,例如视频播放器或视频聊天,请使用此选项。

后者可防止系统本身进入睡眠状态,但允许屏幕变暗并最终完全关闭。对于长时间运行的计算和只需要音频的应用程序很有用。

实际的代码反映了你所拥有的:

//reasonForActivity is a descriptive string used by the system whenever it needs 
//  to tell the user why the system is not sleeping. For example, 
//  "Mail Compacting Mailboxes" would be a useful string.

//  NOTE: IOPMAssertionCreateWithName limits the string to 128 characters. 
CFStringRef* reasonForActivity= CFSTR("Describe Activity Type");

IOPMAssertionID assertionID;
IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, 
                                    kIOPMAssertionLevelOn, reasonForActivity, &assertionID); 
if (success == kIOReturnSuccess)
{

    //Add the work you need to do without 
    //  the system sleeping here.

    success = IOPMAssertionRelease(assertionID);
    //The system will be able to sleep again. 
}

用户显式触发睡眠(例如合上盖子或在 菜单中选择它)或系统使用电池供电时,仍然可以覆盖电源断言。

您在让代码正常工作时遇到问题吗?

于 2013-07-20T15:48:15.113 回答
0

每个值的文档都提供了有关它们作用的更多信息。

kIOPMAssertionTypePreventUserIdleSystemSleep

防止系统由于缺乏用户活动而自动休眠。... 系统可能仍因盖子关闭、Apple 菜单、电池电量不足或其他睡眠原因而处于睡眠状态。此断言不会将系统置于黑暗唤醒状态。

kIOPMAssertionTypeNoIdleSleep

启用后系统不会空闲睡眠。请注意,系统可能会因其他原因而休眠。...系统将宁愿进入黑暗唤醒状态,或者如果已经存在则保持在黑暗唤醒状态,而不是进入睡眠状态。

kIOPMAssertionTypePreventSystemSleep

防止系统休眠并允许系统在 Dark Wake 中驻留任意时间长度。...系统将宁愿进入黑暗唤醒状态,或者如果已经存在则保持在黑暗唤醒状态,而不是进入睡眠状态。

这个措辞似乎暗示第一个选项由于缺乏活动而防止空闲睡眠,第二个选项做同样的事情但更喜欢进入黑暗唤醒而不是睡眠,第三个选项完全阻止睡眠以支持黑暗唤醒。

查看电源管理代码中的PMAssertions.c以及iokit内核代码中的 IOPMrootDomain.cpp ,它似乎kIOPMAssertionTypeNoIdleSleep被视为 的别名kIOPMAssertionTypePreventUserIdleSystemSleep,而kIOPMAssertionTypePreventSystemSleep处理方式不同。设置kIOPMAssertionTypePreventSystemSleep会创建一个内核断言,该断言完全防止系统休眠,除非在电池电量不足或热紧急情况等极端情况下。此外,这仅适用于计算机连接到外部电源时,除非设置了特殊标志。

实际上,似乎大多数 Mac 应用程序kIOPMAssertionTypePreventUserIdleSystemSleep在执行后台任务时都使用它来防止睡眠。例如,Time Machine 在备份时设置此类型的断言。一个例外是 Internet 共享,它用于kIOPMAssertionTypePreventSystemSleep在连接到外部电源时使计算机无限期地保持清醒。请注意,某些用户可能会发现此行为出乎意料或不受欢迎。[ 1 ][ 2 ]

总之:

  • 如果要防止计算机因不活动而进入睡眠状态,请使用kIOPMAssertionTypePreventUserIdleSystemSleep.
  • kIOPMAssertionTypePreventSystemSleep除非您有理由完全阻止系统睡眠,否则请避免使用。
于 2021-02-07T22:16:01.943 回答