So I have an application that fires a series of asynchronous events and then writes the results to a buffer. The problem is that I want the buffer to be written to synchronously (in the thread that spawned the asynchronous process)
skeleton code is as such
let Session = NSURLSession.sharedSession()
let TheStack = [Structure]()
//This gets called asynchronously, e.g. in threads 3,4,5,6,7
func AddToStack(The Response) -> Void {
TheStack.insertAt(Structure(The Response), atIndex: 0))
if output.hasSpaceAvailable == true {
// This causes the stream event to be fired on mutliple threads
// This is what I want to call back into the original thread, e.g. in thread 2
self.stream(self.output, handleEvent: NSStreamEvent.hasSpaceAvailable)
}
}
// This is in the main loop, e.g. thread 2
func 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
}
}
The problem is the thread that calls is dataTaskWithRequest
is in thread, say, 3. The completion handler fires in many different threads and causes case NSStreamEvent.HasSpaceAvailable:
to be running in thread 3, plus all the threads that they existed in.
My question is: How do I make it so that self.stream(self.output, handleEvent: NSStreamEvent.hasSpaceAvailable)
is called in thread 3, or what-ever the original thread was to prevent this tripping over of each other in the output phase.
Thanks in advance!
NOTE: The thread that contains the input/output handling was created with NSThread.detachNewThreadSelector
NSThread.detachNewThreadSelector
in code written after iOS 4, you're doing something wrong. If you're using it in older code than that (or pre-10.6 code), you're still probably doing something wrong. The fact that you're even discussing the specific thread something runs on in ObjC code means you're approaching the problem incorrectly (and that's why you're having these problems). Start by reading Apple's "Migrating Away From Threads" (developer.apple.com/library/ios/documentation/General/…). – HygroscopeperformSelector
family over GCD when possible, since it hides and handleswaitUntilDone
for you, Here is a discussion you may find useful: https://mcmap.net/q/45398/-performselector-may-cause-a-leak-because-its-selector-is-unknown. – Simonson