Swift 2 - iOS - Dispatch back to originating thread Swift 2 - iOS - Dispatch back to originating thread multithreading multithreading

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.