2011-04-08 440 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

相關問題