aufgerufen Ich muss mehrere NSOperation
s zusammenfassen, die Netzwerkaufrufe in einem NSOperationQueue
tun und dann warten, bis alle abgeschlossen sind.Asynchroner Rückruf in NSOperation innerhalb von NSOperationQueue wird nie
Ich füge alle NSOperation
s zu meinem NSOperationQueue
hinzu und rufe dann operationQueue.waitUntilAllOperationsAreFinished()
an. Das funktioniert, aber es wartet unbegrenzt, da die Callbacks in NSOperations
, die den Status der Operation auf 'beendet' setzen, nie aufgerufen werden.
Ich verwende die folgende NSOperation
Unterklasse:
class ConcurrentOperation: NSOperation
{
enum State: String
{
case Ready, Executing, Finished
private var keyPath: String
{
return "is" + self.rawValue
}
}
var state: State = State.Ready {
willSet (newValue)
{
self.willChangeValueForKey(newValue.keyPath)
self.willChangeValueForKey(self.state.keyPath)
}
didSet
{
self.didChangeValueForKey(oldValue.keyPath)
self.didChangeValueForKey(self.state.keyPath)
}
}
}
extension ConcurrentOperation
{
override var ready: Bool {
return super.ready && self.state == .Ready
}
override var executing: Bool {
return self.state == .Executing
}
override var finished: Bool {
return self.state == .Finished
}
override var concurrent: Bool {
return true
}
override var asynchronous: Bool {
return true
}
}
extension ConcurrentOperation
{
override func start()
{
if self.cancelled
{
self.state = .Finished
return
}
self.state = .Executing
self.main()
}
override func cancel()
{
self.state = .Finished
}
}
Dies basiert auf einem Raywenderlich Tutorial und https://gist.github.com/calebd/93fa347397cec5f88233.
Was dies tun sollten, ist die NSOperationQueue sagen, dass nur dann, wenn die main()
Methode in einer Unterklasse von ConcurrentOperation
den Staat .Finished
setzt er abgeschlossen ist. Und das wird auch durch die Operation erfüllt.
jedoch, Wenn ich die folgende main()
Methode in einer solchen ConcurrentOperation
Unterklasse bauen, die NSOperationQueue
hört nie auf, wie die asynchronen Teil nie genannt wird:
override func main()
{
dispatch_async(dispatch_get_main_queue(), {
sleep(1)
self.state = .Finished // never called!
})
}
Das Problem mit einem der gleiche ist Firebase-Query Callback, den ich in meiner App verwende.
Ich versuchte, die concurrent: Bool
Eigenschaft zu überschreiben und true
zurückgeben, aber das repariert es auch nicht.
Wie kann ich erreichen, dass asynchrone Aufgaben tatsächlich in meiner ConcurrentOperation
Unterklasse 'main()
Methode ausgeführt werden?
Vielen Dank!
Rufen Sie 'waitUntilAllOperationsAreFinished' in der Hauptwarteschlange auf? Wenn ja, dann hast du die Hauptwarteschlange blockiert und der 'dispatch_async (dispatch_get_main_queue() ...' Code bekommt keine Chance – Paulw11
auszuführen. Ich habe das in einem 'dispatch_async (_, _) 'Block, es hat die Hauptwarteschlange blockiert. Du bist großartig! Danke! Wenn du eine normale Antwort auf meine Frage schreibst, werde ich sie als richtig markieren. @ Paulw11 – florianpfisterer