0Pricing
Swift Academy · Lekcja

Main Thread Checker i zawieszanie aplikacji

Wykrywanie pracy interfejsu na wątkach działających w tle i rozwiązywanie zawieszeń głównego wątku.

Main Thread Checker i zawieszanie aplikacji to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 3 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.

Main Thread Checker

Main Thread Checker (MTC) to narzędzie diagnostyczne Xcode, które w czasie działania zgłasza wywołania interfejsów API UIKit/AppKit wykonywane z wątków działających w tle.

// Enabled by default in Xcode Debug scheme:
// Product → Scheme → Edit → Diagnostics → ☑ Main Thread Checker
// Violating calls log a purple runtime warning in Xcode

Typowe naruszenia MTC

Aktualizowanie interfejsu użytkownika w completion handlerach lub kolejkach działających w tle należy do najczęstszych naruszeń.

URLSession.shared.dataTask(with: url) { data, _, _ in
  self.label.text = "Done"  // VIOLATION: background thread
}.resume()
// Fix:
DispatchQueue.main.async { self.label.text = "Done" }

MTC z async/await

Oznaczenie klasy lub funkcji za pomocą @MainActor gwarantuje, że wszystkie jej metody będą wykonywane w wątku głównym.

@MainActor
final class ProfileViewModel: ObservableObject {
  @Published var name = ""
  func load() async {
    name = try? await fetchName()  // always on main thread
  }
}

Czym są zawieszenia?

Zawieszenie występuje, gdy wątek główny jest zablokowany zbyt długo, przez co aplikacja przestaje odpowiadać. Watchdog systemu iOS kończy działanie aplikacji, która zawiesza się podczas uruchamiania (>20 s) lub po działaniu użytkownika.

// Common causes:
// - Synchronous network calls on main thread
// - Heavy computation blocking main run loop
// - Deadlocks between DispatchQueues

Szablon Hangs w Instruments

Instrument Hangs w Xcode 14 i nowszych rejestruje zdarzenia zawieszeń wraz z pełnymi śladami stosu, aby ułatwić diagnozowanie blokowania wątku głównego.

// Instruments → Hangs template
// Shows hang duration (ms), call stack, and responsible frame
// Look for synchronous I/O or heavy loops

Main Thread Checker w testach

MTC działa również podczas testów interfejsu użytkownika. Należy skonfigurować go w schemacie testów, aby wykrywać naruszenia w zautomatyzowanych scenariuszach interfejsu.

// XCTestScheme Diagnostics → ☑ Main Thread Checker
// UI test violation = instant fail in CI

Raporty zawieszeń MetricKit

MetricKit zbiera raporty zawieszeń z aplikacji produkcyjnych w MXHangDiagnosticPayload.

func didReceive(_ payloads: [MXDiagnosticPayload]) {
  payloads.compactMap { $0.hangDiagnostics }.flatMap { $0 }.forEach {
    print($0.callStackTree)
  }
}

Wykrywanie zawieszeń za pomocą Instruments

Należy nagrać ślad i wyszukać przedziały czasu, w których wątek główny wykonuje kod, ale łącze wyświetlania nie działa (pominięte klatki).

// Time Profiler: look for long CPU bursts on main thread
// Core Animation: FPS drops to 0 during hang
// Hangs instrument: highlights exact frames where hang occurred

Naprawianie typowych zawieszeń za pomocą kodu asynchronicznego

Ciężkie obliczeniowo operacje należy przenieść poza wątek główny za pomocą Task.detached lub async let.

// HANG:
let processed = heavyProcessing(image)  // blocks main thread
// FIX:
let processed = await Task.detached(priority: .userInitiated) {
  heavyProcessing(image)
}.value

Unikanie synchronicznych interfejsów API w wątku głównym

Synchroniczne operacje wejścia-wyjścia na plikach i wywołania sieciowe należy zastąpić ich asynchronicznymi odpowiednikami lub przenieść do kolejki działającej w tle.

// HANG: synchronous file read on main thread
let data = try! Data(contentsOf: largeFileURL)
// FIX:
let data = try await Task.detached { try Data(contentsOf: largeFileURL) }.value

Główna pętla zdarzeń i zegary

Długotrwałe operacje w głównej pętli zdarzeń (w wywołaniach zwrotnych RunLoop.main) również powodują zawieszenia. Obliczenia należy przenieść poza główną pętlę.

// AVOID: heavy work in main-thread timer callback
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
  processAllItems()  // slow!
}
// PREFER: dispatch to background
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
  Task.detached { processAllItems() }
}

Szybkie sprawdzenie

Co gwarantuje dodanie @MainActor do klasy w odniesieniu do wywołań jej metod?

Podsumowanie lekcji

Należy włączyć Main Thread Checker w schemacie Debug, aby wykrywać naruszenia polegające na aktualizowaniu interfejsu z wątka działającego w tle. Adnotację @MainActor należy stosować w modelach widoków i widokach. Ciężkie operacje należy przenosić poza wątek główny za pomocą Task.detached lub kolejek działających w tle. Do diagnozowania rzeczywistych zawieszeń należy używać instrumentu Hangs oraz MXHangDiagnosticPayload z MetricKit.

Często zadawane pytania

Czy lekcja „Main Thread Checker i zawieszanie aplikacji” jest bezpłatna?

Tak — pełny tekst „Main Thread Checker i zawieszanie aplikacji” 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 „Main Thread Checker i zawieszanie aplikacji”?

Wykrywanie pracy interfejsu na wątkach działających w tle i rozwiązywanie zawieszeń głównego wątku. Ć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 3 z 4.

Ile czasu zajmuje lekcja „Main Thread Checker i zawieszanie aplikacji”?

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. Podstawy Instruments: Time Profiler
  2. Instruments Allocations i Leaks
  3. Main Thread Checker i zawieszanie aplikacji
  4. Optymalizacja gorących ścieżek: COW, inlining i specjalizacja
← Powrót do Swift Academy