2016-07-30 14 views
1

Ich habe Zellen, die Schaltflächen haben, die das Herunterladen ihrer entsprechenden PDF aus dem Internet auslösen. Ich möchte es so, dass immer nur ein Download gleichzeitig stattfinden kann, und die anderen (wenn ihre Schaltfläche angeklickt wird) warten, bis es fertig ist.Warten bis Boolean in Swift True ist?

Ich kann keine Art von Warteschlange verwenden, da die Warteschlangenoperation die Download-Methoden aufruft, aber nicht darauf wartet, dass sie abgeschlossen werden, bevor sie fortfahren.

Gibt es eine Möglichkeit, dass ich nur weitergehen kann, sobald die Download-Funktion beendet hat, dass sie bereit ist, indem sie einen booleschen Wert oder etwas übergibt? Ich bin hier ziemlich verloren, daher wird jede Richtung sehr geschätzt.

+0

ein Tutorial auf GCD nachschlagen. Sie möchten einen Versand-Semaphor verwenden. – Alexander

+0

Uhr. Dies. Video. https://developer.apple.com/videos/play/wwdc2015/226/ – matt

+0

Sie müssen dispatch_semaphore für verwenden und signalisieren, wenn Sie einen Prozess aus der Warteschlange beenden –

Antwort

1

Ich kann keine Art von Warteschlange verwenden, da die Warteschlangenoperation die Downloadmethoden aufruft, aber nicht darauf wartet, dass sie abgeschlossen werden, bevor sie fortfahren.

Dies kann mit NSOperation Queues erreicht werden. Der Schlüssel ist, dass Ihre Download-Aufgaben async sein müssen NSOperation Unterklassen, in denen Sie den Vorgang als abgeschlossen markieren, wenn der Download abgeschlossen ist. Noch wichtiger ist, dass diese Operationen in einer seriellen Warteschlange eingereiht werden sollten. Dann werden Operationen nur einzeln in FIFO-Reihenfolge ausgeführt.

Es erfordert jedoch ein wenig Standard, um NSOperations auf diese Weise einzurichten. Eine andere gute Möglichkeit ist die Verwendung von Dispatch Groups.

// A serial queue ensures only one operation is executed at a time, FIFO 
let downloadsQueue = dispatch_queue_create("com.youapp.pdfdownloadsqueue", DISPATCH_QUEUE_SERIAL) 
let downloadGroup = dispatch_group_create() 

func queueDownload(from url: NSURL) { 
    // Register this download task with the group 
    dispatch_group_enter(downloadGroup) 

    // Async dispatch the download task to our serial queue, 
    // so that it returns control back without blocking the main thread 
    dispatch_async(downloadsQueue) { 
     downloadPDF(with: url) { (pdf, error) in 
      // handle PDF data/error 
      // { .. } 

      // leave the dispatch group in the completion method, 
      // notifying the group that this task is finished 
      dispatch_group_leave(downloadGroup) 
     } 
    } 
} 

func downloadPDF(with url: NSURL, completion: (pdf: NSData?, error: ErrorType?) ->()) { 
    // make network request 
    // call completion with PDF data or error when the download request returns 
}