Итак, у меня есть приложение, которое запускает серию асинхронных событий, а затем записывает результаты в буфер. Проблема в том, что я хочу, чтобы буфер записывался синхронно (в потоке, породившем асинхронный процесс)
каркасный код как таковой
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
}
}
Проблема в том, что поток, который вызывает dataTaskWithRequest
, находится в потоке, скажем, 3. Обработчик завершения срабатывает во многих разных потоках и заставляет case NSStreamEvent.HasSpaceAvailable:
выполняться в потоке 3, а также во всех потоках, в которых они существовали.
Мой вопрос: как мне сделать так, чтобы self.stream(self.output, handleEvent: NSStreamEvent.hasSpaceAvailable)
вызывался в потоке 3 или каким-либо исходным потоком, чтобы предотвратить это спотыкание друг о друга на этапе вывода.
Заранее спасибо!
ПРИМЕЧАНИЕ. Поток, содержащий обработку ввода-вывода, был создан с помощью NSThread.detachNewThreadSelector.
NSThread.detachNewThreadSelector
в коде, написанном после iOS 4, вы делаете что-то не так. Если вы используете его в более старом коде (или в коде до 10.6), вы все еще, вероятно, делаете что-то не так. Тот факт, что вы даже обсуждаете конкретный поток, в котором что-то работает в коде ObjC, означает, что вы неправильно подходите к проблеме (и поэтому у вас возникают эти проблемы). Начните с прочтения документа Apple «Миграция от потоков» (для разработчиков). .apple.com/library/ios/documentation/General/). - person Rob Napier   schedule 20.01.2016performSelector
вместо GCD, когда это возможно, поскольку оно скрывает и обрабатываетwaitUntilDone
для вас. Вот обсуждение, которое может оказаться полезным: stackoverflow. com/a/34540787/218152. - person SwiftArchitect   schedule 21.01.2016