So, quite accidentally, I managed to make an iPhone app that continued to run in the background. I had a controller action that was hooked up to a button. Clicking the button would play the sound using OpenAL. Now, I was more interested in seeing if the code worked than in trying to make it work well. As a result, the action handler blocked until the sound clip was over. Because of the nature of OpenAL, you need to poll an audio source to tell when it has finished playing. Furthermore, it seems that OpenAL gets confused if the audio route changes while it is playing back audio. In my case, all my audio sources got stuck in a "playing" state that never finished.
Since my prototype code didn't handle audio route changes, my polling loop turned into an infinite loop. With this loop blocking the primary run loop of my app, the quit message was never processed. The application's hosting process continued to run for quite a while. I could see output continue to get spewed to the debug log.
Now, this isn't a very practical solution. Blocking your process' run loop has other, bad side-effects. However, considering how paranoid Apple is about background processes and battery life, I was astounded that the OS didn't kill my obviously runaway process. Though the device itself doesn't seem to enforce the "no background processes" mandate, it likely that an app that did this would not make it past the App Store review process.
In my case, it was easy enough to fix up the code. I was waiting until the audio finished playing because I wanted to do some cleanup. It was easy enough to make a watchdog NSTimer that would occasionally poll my audio sources to see if they had finished playing and, if so, perform the cleanup.
No comments:
Post a Comment