如何以编程方式阻止Mac进入睡眠状态?

use*_*769 27 macos objective-c

有没有办法阻止Mac使用Objective-C以编程方式进入睡眠状态?Apple开发站点上的I/O工具包基础部分告诉我驱动程序会收到空闲/系统睡眠的通知,但我找不到阻止系统休眠的方法.它甚至可能吗?

我遇到了一些使用咖啡因,摇晃,失眠甚至AppleScript的其他解决方案,但我想在Objective-C中这样做.谢谢.

Ann*_*nne 26

这是官方的Apple文档(包括代码片段):
技术问答QA1340 - 如何防止睡眠?

引用:在Mac OS X 10.6 Snow Leopard中使用I/O Kit防止睡眠:

#import <IOKit/pwr_mgt/IOPMLib.h>

// 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. 
}
Run Code Online (Sandbox Code Playgroud)

对于较旧的OSX版本,请检查以下内容:
技术问答QA1160 - 如何在应用程序运行时阻止系统睡眠?

Quote: UpdateSystemActivity的示例用法(规范方式<10.6)

#include <CoreServices/CoreServices.h>

void
MyTimerCallback(CFRunLoopTimerRef timer, void *info)
{
    UpdateSystemActivity(OverallAct);
}


int
main (int argc, const char * argv[])
{
    CFRunLoopTimerRef timer;
    CFRunLoopTimerContext context = { 0, NULL, NULL, NULL, NULL };

    timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 30, 0, 0, MyTimerCallback, &context);
    if (timer != NULL) {
        CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);
    }

    /* Start the run loop to receive timer callbacks. You don't need to
    call this if you already have a Carbon or Cocoa EventLoop running. */
    CFRunLoopRun();

    CFRunLoopTimerInvalidate(timer);
    CFRelease(timer);

    return (0);
}
Run Code Online (Sandbox Code Playgroud)


Gra*_*iln 10

Apple的Q&A1340取代了Q&A1160.最新的问答回答了一个问题:问:当计算机进入睡眠状态或从睡眠中醒来时,我的应用程序如何得到通知?如何防止睡眠?

Q&A1340的清单2 :

#import <IOKit/pwr_mgt/IOPMLib.h>

// 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. 
}
Run Code Online (Sandbox Code Playgroud)

请注意,您只能停止空闲时间睡眠,而不能停止用户触发睡眠.

对于支持Mac OS X 10.6及更高版本的应用程序,请使用新的IOPMAssertion系列函数.这些功能允许其他应用程序和实用程序看到您的应用程序不想睡觉的愿望; 这对于与第三方电源管理软件无缝协作至关重要.


edc*_*591 2

只需创建一个 NSTimer 来触发一个函数

UpdateSystemActivity(OverallAct);
Run Code Online (Sandbox Code Playgroud)

我很确定这正是咖啡因的作用。

  • 我认为他说得有道理。苹果描述的“令人惊奇”的技术是一个非常糟糕和蹩脚的解决方案,因为你必须将代码嵌入到那个东西上,这使得它变得复杂。现在想象一下代码是否是异步的。而且,苹果甚至懒得编写没有错误的代码。苹果零星。 (4认同)
  • 请避免这种伎俩。请改用 Q&amp;A1340 中记录的 Apple 认可的技术。 (3认同)