Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code in NSTimer prevents automatic sleep

Tags:

sleep

macos

cocoa

I have an NSTimer running in my application that collects some data and sends it to a server periodically. In production the timer will fire every few hours.

I am worried about interfering with automatic sleep. In testing, some combinations of timer and sleep time prevent automatic sleep entirely — the display sleeps, the system keeps running. Setting my NSTimer to one minute always stops it.

Some Mac applications are notorious for interfering with automatic sleep when running (or all the time, if they install a daemon). What actions stop the system from sleeping and how can I run periodic tasks safely?

like image 421
s4y Avatar asked Mar 31 '09 16:03

s4y


2 Answers

NSLog(), at least when it is logging to /var/log/system.log, can prevent idle sleep. I tested with a launchd daemon that would call NSLog(@"test") every minute and with a system sleep idle time of 1 minute, and the system never went to sleep. By commenting out that NSLog line, the system went to sleep after 1 minute.

Here's the only reference I found to someone else experiencing this issue.

like image 90
Noah Harrison Avatar answered Oct 16 '22 20:10

Noah Harrison


Accessing the disk will prevent your computer from sleeping, according to Apple's article "Mac OS X: Why your Mac might not sleep or stay in sleep mode".

Additionally, my testing has shown that the priority of a thread also has an impact on whether or not a computer will sleep. The following code with a timer will allow a computer to sleep.

@implementation AppController

-(void)timerFired:(NSTimer *)aTimer
{

}

-(void)spawnThread
{
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   [NSThread setThreadPriority:0.0];

   [NSTimer scheduledTimerWithTimeInterval:20 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES];

   while(1) //Run forever!
   {
      [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:300]];
   }

   [pool drain];
}

-(void)awakeFromNib
{
   [NSThread detachNewThreadSelector:@selector(spawnThread) toTarget:self withObject:nil];
}

@end

Removal of the setThreadPriority call will prevent the computer from sleeping.

like image 36
JimDusseau Avatar answered Oct 16 '22 21:10

JimDusseau