Swift 2 - iOS - Dispatch back to originating thread
Alright, for the curious onlooker I, with aid from comments to the question I have figured out how to do what I originally asked in the question (whether or not this ultimately gets rewritten to use GCD is a different question)
The solution (with a slightly increased scope into the code) is to use performSelector with a specific thread.
final class ArbitraryConnection {internal var streamThread: NSThreadlet Session = NSURLSession.sharedSession()let TheStack = [Structure]()//This gets called asynchronously, e.g. in threads 3,4,5,6,7func AddToStack(The Response) -> Void { TheStack.insertAt(Structure(The Response), atIndex: 0)) if output.hasSpaceAvailable == true { // This causes the stream event to be fired on multiple threads // This is what I want to call back into the original thread, e.g. in thread 2 // Old way self.stream(self.output, handleEvent: NSStreamEvent.hasSpaceAvailable) // New way, that works if(streamThread != nil) { self.performSelector(Selector("startoutput"), onThread: streamThread!, withObject: nil, waitUntilDone: false) } }}func open -> Bool { // Some stuff streamThread = NSThread.currentThread()}final internal func startoutput -> Void { if(output.hasSpaceAvailable && outputIdle) { self.stream(self.output, handleEvent: NSStreamEvent.HasSpaceAvailable) }}// This is in the main loop, e.g. thread 2func stream(aStream: NSStream, handleEvent: NSStreamEvent) { switch(NSStreamEvent) { case NSStreamEvent.OpenCompleted: // Do some open stuff case NSStreamEvent.HasBytesAvailable: Session.dataTaskWithRequest(requestFromInput, completionHandler: AddToStack) case NSStreamEvent.HasSpaceAvailable: // Do stuff with the output case NSStreamEvent.CloseCompleted: // Close the stuff }}}
So use performSelector on the object with the selector and use the onThread to tell it what thread to pass to. I check both before performing the selector and before doing the call to make sure that output has space available (make sure I don't trip over myself)
It won't let me comment on on the thread above (this is what I get for lurking), but one thing to be aware of is that your current code could deadlock your UI if you use waitUntilDone
or performBlockAndWait
.
If you go that route you need to be absolutely sure that you don't call this from the mainThread or have a fallback case that spawns a new thread.