0Pricing
Swift Academy · Lekcja

Harmonogramy i wątki

Kontrolowanie wykonywania za pomocą receive(on:) i subscribe(on:).

Harmonogramy i wątki to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.

Schedulery w Combine

Scheduler w Combine określa kiedy i gdzie wykonywana jest praca — który wątek lub kolejka wykonuje operatory i dostarcza wartości subskrybentom.

Kontrolowanie schedulerów jest niezbędne, aby aktualizacje interfejsu użytkownika wykonywały się w głównym wątku, a ciężkie operacje poza nim.

Dwa kluczowe operatory

Combine udostępnia dwa operatory do kontrolowania wykonywania wątkowego:

  • subscribe(on:) — określa, gdzie rozpoczyna się subskrypcja i praca w górę potoku
  • receive(on:) — określa, gdzie dostarczane są wartości w dół potoku

Wpływają one na różne końce potoku.

receive(on:)

receive(on:) przenosi wszystko, co znajduje się za nim, na wskazany scheduler. Najczęściej stosuje się go do powrotu na główną kolejkę przed aktualizacją interfejsu użytkownika.

apiClient.fetchUser(id: 1)
    .receive(on: DispatchQueue.main)
    .sink { user in
        self.nameLabel.text = user.name
    }
    .store(in: &cancellables)

subscribe(on:)

subscribe(on:) określa wątek, w którym publisher zaczyna produkować wartości, oraz miejsce wykonywania operatorów znajdujących się wyżej w potoku. Użyj go, aby przenieść kosztowną konfigurację poza główny wątek.

heavyPublisher
    .subscribe(on: DispatchQueue.global(qos: .userInitiated))
    .receive(on: DispatchQueue.main)
    .sink { result in
        self.update(result)
    }
    .store(in: &cancellables)

subscribe(on:) a receive(on:)

Zapamiętaj kierunki działania:

  • subscribe(on:) wpływa na część upstream — określa, gdzie rozpoczyna się praca
  • receive(on:) wpływa na część downstream — określa, gdzie dostarczane są wyniki

Typowy wzorzec wykorzystuje subscribe(on:) do pracy w tle oraz receive(on:) do dostarczania wyników w głównym wątku.

DispatchQueue jako scheduler

DispatchQueue jest zgodny z protokołem Scheduler. DispatchQueue.main dostarcza wartości w głównym wątku, a globalne kolejki wykonują pracę współbieżnie w tle.

let background = DispatchQueue.global(qos: .background)

publisher
    .map { expensiveTransform($0) }
    .subscribe(on: background)
    .receive(on: DispatchQueue.main)
    .sink { self.render($0) }
    .store(in: &cancellables)

RunLoop jako scheduler

RunLoop to kolejny scheduler, powiązany z pętlą zdarzeń wątku. RunLoop.main dostarcza wartości w koordynacji ze zdarzeniami interfejsu użytkownika, co może mieć znaczenie na przykład dla płynności przewijania.

timerPublisher
    .receive(on: RunLoop.main)
    .sink { _ in
        self.tick()
    }
    .store(in: &cancellables)

DispatchQueue a RunLoop

Oba rozwiązania mogą dostarczać wartości w głównym wątku, ale nieznacznie się różnią:

  • DispatchQueue.main — planuje wykonanie również podczas śledzenia przewijania
  • RunLoop.main — odracza pracę, gdy pętla zdarzeń działa w trybie tracking

W przypadku większości aktualizacji interfejsu po pracy asynchronicznej DispatchQueue.main jest bezpieczniejszym wyborem domyślnym.

Operatory czasowe schedulerów

Operatory takie jak debounce, throttle i delay przyjmują argument scheduler, który decyduje, która kolejka obsługuje ich odmierzanie czasu.

searchTextPublisher
    .debounce(for: .milliseconds(300), scheduler: DispatchQueue.main)
    .sink { query in
        self.runSearch(query)
    }
    .store(in: &cancellables)

Typowy błąd związany z wątkami

Aktualizowanie interfejsu użytkownika poza głównym wątkiem powoduje awarie lub błędy wyświetlania. Jeśli po publisherze działającym w tle zapomnisz o receive(on: DispatchQueue.main), Twój sink może wykonać się w wątku działającym w tle.

Zawsze dostarczaj wartości używane przez interfejs użytkownika za pośrednictwem głównego schedulera.

Połączenie wszystkiego

Solidny potok rozpoczyna pracę w tle, tam ją przetwarza, a następnie dostarcza wyniki do głównego wątku w celu ich wyświetlenia.

imageURLPublisher
    .subscribe(on: DispatchQueue.global())
    .flatMap { url in downloadImage(url) }
    .map { resize($0) }
    .receive(on: DispatchQueue.main)
    .sink { self.imageView.image = $0 }
    .store(in: &cancellables)

Szybki test

Sprawdź swoją wiedzę na temat schedulerów.

Podsumowanie

Poznałeś(-aś) sposoby kontrolowania wykonywania wątkowego w Combine:

  • subscribe(on:) — określa, gdzie rozpoczyna się praca w górę potoku
  • receive(on:) — określa, gdzie dostarczane są wyniki
  • DispatchQueue i RunLoop jako schedulery
  • Zawsze dostarczaj aktualizacje interfejsu użytkownika w głównym wątku

Właściwe planowanie pracy zapewnia responsywność aplikacji i zapobiega awariom.

Często zadawane pytania

Czy lekcja „Harmonogramy i wątki” jest bezpłatna?

Tak — pełny tekst „Harmonogramy i wątki” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Harmonogramy i wątki”?

Kontrolowanie wykonywania za pomocą receive(on:) i subscribe(on:). Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Swift Academy?

Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Harmonogramy i wątki”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?

Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Przekształcanie i łączenie strumieni
  2. Harmonogramy i wątki
  3. Operatory obsługi błędów
  4. Niestandardowi publisherzy i subskrybenci
← Powrót do Swift Academy