Miałem dzisiaj dość interesującą awaria exc_bad_access. Po wielu kopaniu wymyśliłem następujące informacje (działające w symulatorze):W jaki sposób NSLog może spowodować awarię kodu?
Jeśli po prostu uruchomiłem kod, aplikacja losowo ulegał awarii w losowym punkcie podczas ładowania danych do mojego zarządzanego obiektu. Z tego, co mogłem powiedzieć, to zawsze się zawieszało, gdy ładowałem dane do zarządzanego obiektu - nie na przekroje przekształcone z mojego Dysku JSON na dane do faktycznie używanego obiektu (od łańcuchów i NSNulls do ints/floats i nils)
Losowe awarie są oczywiście złe, więc próbowałem przejść przez proces w debugerze, ale to nie okazało się praktyczne - przetwarzałem wiele obiektów, więc przechodziłem między nimi jeden po drugim po prostu nie działa. Postanowiłem więc dodać trochę NSLogów, aby śledzić proces i spróbować rozpoznać wzór w ten sposób.
Natychmiastowe rozwiązanie awarii.
Tylko jeden NSLog, w dowolnym miejscu procesu, zapobiegał awariom.
W końcu śledziłem drogę do stosu i znalazłem faktyczny problem: uzyskiwałem dostęp do zarządzanego obiektu w środowisku gwintowanym, ale NIE z powiązanej metody performBlockAndWait: MOC. W tym momencie katastrofa była dla mnie niesamowicie oczywista - jestem zszokowany, że wcześniej nie miałem więcej problemów. Mogę się założyć, że pomiędzy posiadaniem "małego" zestawu danych testowych 2-3 obiektów i posiadającego kod debugowania z NSLogs, błąd został dość skutecznie zamaskowany wcześniej ... ale pozostaje pytanie:
Dlaczego czy NSLog zapobiega awarii aplikacji? Jak na Ziemi fragment kodu bez efektów ubocznych może zmienić wykonanie reszty aplikacji? To nie ma sensu!
czy używasz w dowolnym miejscu performSelector: method i selektor, który zwraca parametr id id, nie jako parametr? Czasami NSLog może zapobiegać błędom spowodowanym tymi błędami.W takim przypadku trzeba użyć NSInvocation – BergP