2011-04-08 446 views
23

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

我遇到过一些其他的解决方案,使用咖啡因,jiggler,失眠,甚至是AppleScript,但我想在Objective-C中做到这一点。谢谢。

回答

4

只需创建一个触发的功能与此

UpdateSystemActivity(OverallAct); 

我敢肯定,这正是咖啡因做一个NSTimer。

+2

请避免这个诡计。请使用Q&A1340中记录的Apple认可的技术。 – 2011-12-11 01:04:49

+2

我认为他有一点。 Apple描述的“惊人”技术是一个非常糟糕和糟糕的解决方案,因为您必须将代码嵌入到该事物中,使其变得复杂。现在想象一下,如果代码是异步的。另外,苹果甚至不会无心编写没有错误的代码。零星的苹果。 – SpaceDog 2014-12-18 21:53:07

+0

这在OSX 10.8中已弃用。 – Volomike 2016-03-25 22:05:28

19

这是苹果官方文件(包括代码片段):
Technical Q&A QA1340 - How to I prevent sleep?

报价:在Mac OS X防止使用I/O Kit的睡眠10.6雪豹:

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

对于较旧的OSX版本,请检查以下内容:
Technical Q&A QA1160 - How can I prevent system sleep while my application is running?

报价: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); 
} 
+0

谢谢,这就是我一直在寻找的。 – user698769 2011-04-09 12:53:48

+0

我不认为这项工作,例如当macbook盖子关闭时......那么你会如何防止睡眠? – 2013-12-30 21:56:29

+0

@DavidKarlsson有两种类型的睡眠; __idle__和__forced__。 __dle__可以由您的应用程序控制,而__forced__不能。关闭MacBook盖子会强制睡眠。 – Andreas 2017-10-01 21:53:23

9

苹果Q&A1340代替Q & A1160。最新Q & A回答了问题“问:当计算机要睡觉或从睡梦中醒来时,我的应用程序如何得到通知?如何防止睡眠?

上市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. 
} 

请注意,您只能停止空闲时间睡觉,睡不着由用户触发。

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

+0

在'CFStringRef *'赋值上,XCode给了我“不兼容的指针类型”。我必须在CFSTR()调用之前添加'(CFStringRef *)'来修复它。另外,您可能想提到需要将'IOKit.framework'添加到他们的项目中。我对这两个都正确吗? – Volomike 2016-03-25 19:52:27

+0

另外,在'IOPMAssertionCreateWithName()'调用中,我必须添加一个星号'* reasonForActivity'才能编译它。 – Volomike 2016-03-25 20:13:45

+0

@Volomike如果您觉得代码有误,请您直接向Apple报告错误(http://bugreport.apple.com),因为列出的代码来自Q&A1340。一旦报告,请随时在此处添加错误编号,以允许其他人将其自己的报告中的错误复制或引用至Apple。 – 2016-03-25 20:50:45

相关问题