Search code examples
iosobjective-cmultithreadingswiftnsthread

Running audio engine in separate thread/process, sending and receiving messages from main thread


I'm writing an iOS application using a separate audio engine which is built in C++. The idea is to have as much of the app as possible written in Swift, running the audio engine as a separate thread or process, and then let the user interface trigger communication with the audio engine.

How is this best achieved?

My first try was to add an intermediate Objective-C++ class (TestEngine) that handles triggering the appropriate C++ code. This Objective-C++ class I initiate in Swift like this:

// Initialize audio engine
let engine = TestEngine()

// Start engine in a new thread
NSThread.detachNewThreadSelector(NSSelectorFromString("startEngine"), toTarget: engine, withObject: nil)

The TestEngine class looks like this:

@implementation TestEngine

- (void) startEngine {
    [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(selectorMethod)
     name:@"testSelector"
     object:nil];

    NSLog(@"StartEngine done on thread:%@", [NSThread currentThread]);

}

- (void) selectorMethod {
    NSLog(@"This is selector, on thread %@", [NSThread currentThread]);
}

- (void)dealloc
{
    NSLog(@"Now deallocing");
}

@end

The problem now is that the object is deallocated right away, before it is able to receive any notifications. I have also tried looking into RunLoops, but haven't been able to find any easy (not too low-level) way to add observers to the RunLoop. Any ideas of how such a solution is best designed on iOS?


Solution

  • I think here there's your answer

    Quoting Apple docs

    Regular notification centers deliver notifications on the thread in which the notification was posted. Distributed notification centers deliver notifications on the main thread. At times, you may require notifications to be delivered on a particular thread that is determined by you instead of the notification center. For example, if an object running in a background thread is listening for notifications from the user interface, such as a window closing, you would like to receive the notifications in the background thread instead of the main thread. In these cases, you must capture the notifications as they are delivered on the default thread and redirect them to the appropriate thread.