Chciałbym podyskutować trochę na temat synchronizacji przy użyciu wielowątkowości w swifcie. Nie mam z tym zbyt dużego doświadczenia, a akurat aktualnie piszę pewną aplikację, w której będzie to wymagane. Mam pewien model, który przy okazji pewnych zmian w interfejsie zaczyna wykonywać dużo obliczeń, których rezultaty są następnie wyświetlane w ViewControllerze. Dlatego postanowiłem przenieść wszystkie te obliczenia na inny wątek. Robię to w taki sposób, że wszystkie funkcje i akcje, które rozpoczynają te zmiany w modelu zamykam w dispatch_async z nową kolejką. W tym modelu istnieje pewna tablica, która jest następnie wyświetlana w UITableView w VC. Ponieważ tablica ta może zostać zmieniona w czasie kiedy VC wczytuje ją do UITableView musiałem zrobić jakieś zabezpieczenie. Póki co rozwiązałem to w taki sposób, że wszystkie zmiany na tej tablicy w modelu przeniosłem do nowej tablicy, powiedzmy _tab. ViewController pobiera dane z tab (bez _). W didSet _tab dodałem
dispatch_sync(dispatch_get_main_queue) { [unowned self] in self.tab = self._tab }
Dzięki temu _tab jest zmieniany tylko w main_queue. Czy to jest dobre podejście? Może ktoś poda jakiś lepszy sposób? Poniżej dodaję troszkę kodu, żeby pokazać o co mi chodziło:
let workingQueue = dispatch_queue_create("workingQueue", DISPATCH_QUEUE_SERIAL)
private let mainQueue = dispatch_get_main_queue()
private var _objects = [WorldObject]() { // This value is being updated on different thread.
didSet {
let changes = _objects.changesFromOldValue(oldValue)
dispatch_sync(mainQueue) { [unowned self] in
self.objects = self._objects
// Notify observers about changes.
if changes.addedValues.count > 0 || changes.removedValues.count > 0 {
self.objectsObservers.notifyObserversAboutChange(changes)
}
}
}
}
private(set) var objects = [WorldObject]() // This value is being updated on main thread, so it's safe to read in ViewController.
Użytkownik Damian Dudycz edytował ten post 05 marca 2016 - 12:35