2014-07-05 27 views
35

Czy istnieje sposób utworzenia wątku roboczego w Swift ?, na przykład, jeśli istnieje duża funkcjonalność, która wymaga wielu obliczeń, a zatem powoduje opóźnienie głównego wątku o kilka sekund, jeśli chciałbym przenieść tę funkcję do oddzielnego wątku lub wątku, który nie blokuje głównego wątku, czy jest jakiś sposób na zrobienie tego za pomocą Swifta?Jak wykonywać wielowątkowość, współbieżność lub równoległość w iOS Swift?

Przeszedłem przez podstawowe i zaawansowane komponenty Dokumentacji Apple dla Swifta, ale nie ma nic o współbieżności ani równoległości, czy ktoś wie coś o tym, jak to zrobić (jeśli to możliwe)?

+0

spróbować zrobić to w Obj-C –

+0

[CwlUtils] (https://github.com/mattgallagher/CwlUtils/) mogą być użyteczne . – Raphael

Odpowiedz

45

Albo można użyć kolejki operacji, też. W Swift 3:

let queue = OperationQueue() 

queue.addOperation() { 
    // do something in the background 

    OperationQueue.main.addOperation() { 
     // when done, update your UI and/or model on the main queue 
    } 
} 

Albo to, albo GCD, który Andy illustrated, praca w porządku.

Zobacz Apple's Concurrency Programming Guide dla względnych zalet kolejki operacji i kolejek wysyłki (aka Grand Central Dispatch, GCD). Chociaż ten przewodnik wciąż ilustruje przykłady przy użyciu Objective-C, API i koncepcje są zasadniczo takie same w Swift (wystarczy użyć składni Swift). Dokumentacja GCD i kolejki operacji w Xcode opisuje zarówno Objective-C, jak i Swift API.


Nawiasem mówiąc, można zauważyć, że zarówno w powyższym przykładzie, jak również Andy'ego GCD demonstracji, użyliśmy „zamknięcia końcowe”. Na przykład, jeśli spojrzeć w definicji addOperationWithBlock, która jest zdefiniowana jako funkcja jednego parametru, który jest „zamknięcie” (który jest analogiczny do bloku, w celu C)

func addOperation(_ block: @escaping() -> Swift.Void) 

że może prowadzić zakładać, że można powołać się go w następujący sposób:

queue.addOperation({ 
    // do something in the background 
}) 

Ale kiedy ostatni parametr funkcji jest zamknięcie, tylna składnia zamknięcie pozwala przyjąć, że ostateczne parametry zamknięcia z nawiasów w funkcji, a przenieś go po funkcji, uzyskując:

queue.addOperation() { 
    // do something in the background 
} 

A ponieważ nie ma nic w nawiasach, można nawet pójść o krok dalej i usunąć te puste nawiasy:

queue.addOperation { 
    // do something in the background 
} 

Mam nadzieję, że pokazuje, jak interpretować funkcję NSOperationQueue/OperationQueue i/lub GCD deklaracje i wykorzystaj je w swoim kodzie.

17

Możesz używać Grand Central Dispatch (GCD) do takich zadań.

Jest to prosty przykład:

let backgroundQueue: dispatch_queue_t = dispatch_queue_create("com.a.identifier", DISPATCH_QUEUE_CONCURRENT) 

// can be called as often as needed 
dispatch_async(backgroundQueue) { 
    // do calculations 
} 

// release queue when you are done with all the work 
dispatch_release(backgroundQueue) 
0

This library pozwala opisać współbieżności w super wyrazisty sposób:

func handleError(_ error) { ... } 

HoneyBee.start(on: DispatchQueue.main) { root in 
    root.setErrorHandler(handleError) 
     .chain(function1) // runs on main queue 
     .setBlockPerformer(DispatchQueue.global()) 
     .chain(function2) // runs on background queue 
     .branch { stem in 
      stem.chain(func3) // runs in parallel with func4 
      + 
      stem.chain(func4) // runs in parallel with func3 
     } 
     .chain(func5) // runs after func3 and func4 have finished 
     .setBlockPerformer(DispatchQueue.main) 
     .chain(updateUIFunc) 
}