各种kIOPMAssertionType之间的区别

时间:2013-07-10 14:03:49

标签: objective-c power-management iokit

kIOPMAssertionTypeNoIdleSleepkIOPMAssertionTypePreventSystemSleepkIOPMAssertionTypePreventUserIdleSystemSleep之间有什么区别?

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

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

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

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

2 个答案:

答案 0 :(得分:1)

Apple已就此问题published a Q&A note,我认为这可以回答您的问题。有问题的示例代码中的关键注释:

// 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. 
}

用户仍然可以通过明确触发睡眠来覆盖电源断言(例如关闭盖子或在菜单中选择它),或者系统是否使用电池供电。

您是否无法使代码正常运行?

答案 1 :(得分:0)

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

kIOPMAssertionTypePreventUserIdleSystemSleep

<块引用>

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

kIOPMAssertionTypeNoIdleSleep

<块引用>

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

kIOPMAssertionTypePreventSystemSleep

<块引用>

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

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

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

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

总结:

  • 如果您想防止计算机因不活动而休眠,请使用 kIOPMAssertionTypePreventUserIdleSystemSleep
  • 避免使用 kIOPMAssertionTypePreventSystemSleep,除非您有 完全阻止系统休眠的原因。