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 XcodeTypowe 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 DispatchQueuesSzablon 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 loopsMain 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 CIRaporty 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 occurredNaprawianie 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)
}.valueUnikanie 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) }.valueGłó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
- Podstawy Instruments: Time Profiler
- Instruments Allocations i Leaks
- Main Thread Checker i zawieszanie aplikacji
- Optymalizacja gorących ścieżek: COW, inlining i specjalizacja