2015-08-28 11 views
10

Czy istnieje narzędzie lub metoda do zlokalizowania silnych cykli odniesień w moim kodzie SWIFT?Jak rozpoznać silne cykle odniesienia w Swift?

silny cykl odniesienia, gdy dwie instancje klas odniesienia siebie bez odpowiednich bezpieczniki (weak/unowned), zapobiegając w ten sposób pojemnik na śmieci z usuwania z nich jednocześnie wszystkie zmienne, że utworzone zatrzymane odwoływania się do tych przedmiotów.

+0

Jestem nowy w tym ekosystemie (więc nie znam Celu C), więc od teraz jest to ARC. –

+0

To jest w porządku, ponieważ koncepcje są w dużej mierze takie same. Byłbym zaskoczony, gdybyś zobaczył dyskusje w silnych cyklach odniesienia Objective-C i nie byliby w stanie natychmiast zastosować tego do twojego programowania Swift (zwłaszcza, że ​​znasz składnię 'unowned' i' weak' w Swift). – Rob

Odpowiedz

0

Możesz to zrobić za pomocą use Instruments. Jako ostatni akapit this article stwierdza:

Po Instruments otwiera, należy uruchomić aplikację i zrobić kilka interakcji, szczególnie w obszarach lub widoku kontrolerów chcesz przetestować. Każdy wykryty wyciek pojawi się jako czerwona linia w sekcji "Wycieki". Widok asystenta obejmuje obszar, w którym Instruments pokaże ci ślad stosu związany z wyciekiem, dając ci wgląd w to, gdzie może być problem, a nawet pozwalając na bezpośrednie przejście do obraźliwego kodu.

1

Użyj przyrządów do sprawdzania wycieków i utraty pamięci. Użyj Mark Generation (Heapshot) w przydziale Allocations na instrumentach.

Do stosowania HowTo Heapshot znaleźć creap pamięci, patrz: bbum blog

Zasadniczo metoda polega na uruchomieniu Instruments przeznaczyć narzędzia, wziąć heapshot uruchom iteracji kodu i podjąć kolejną heapshot powtarzania 3 lub 4 razy. To wskaże pamięć, która jest przydzielana i nie jest zwalniana podczas iteracji.

Aby obliczyć wyniki, należy ujawnić poszczególne alokacje.

Jeśli chcesz zobaczyć, gdzie zachowuje, komunikaty i autoreleases występować jeszcze przez instrumentów użytkowania obiektu:

Run instrumentami, w przydziały ustalone „liczy referencyjnych record” na (dla Xcode 5 i obniżyć trzeba zatrzymać nagrywanie aby ustawić opcję). Powoduje uruchomienie aplikacji, zatrzymanie nagrywania, drążenie w dół, a zobaczysz, gdzie znajdują się wszystkie zachowane, wydania i autorekiety.

+0

W pierwszym zdaniu zobacz: "Oznacz Generację". W blogu autorstwa bbum użyto "Heapshot", więc umieściłem to w parens: "(Heapshot)". – zaph

11

Sposób znalezienia silne cykle odniesienia jest taki sam Swift, jak to jest w celu C.

Uruchomiłbyś aplikację z Xcode, uruchom aplikację wystarczająco, aby zamanifestować cykl, a następnie naciśnij przycisk "debug memory graph" (debug memory graph). Następnie można wybrać niepublikowane obiekt w panelu po lewej stronie i pokaże wykres pamięci, często które mogą wyraźnie silne cykle referencyjne:

debug memory graph

Czasami cykle pamięci nie są tak oczywiste jak to, ale możesz przynajmniej zobaczyć, jaki obiekt ma silne odniesienie do danego obiektu. Jeśli to konieczne, możesz śledzić wstecz i określić, co ma silne odniesienie do tego i tak dalej.

Niekiedy wiadomo, jakiego rodzaju obiekt utrzymuje, silne odniesienie jest niewystarczające i naprawdę chcesz wiedzieć, gdzie w kodzie znajduje się silne odniesienie.Opcja "malloc stack", jak pokazano w https://stackoverflow.com/a/30993476/1271826, może być użyta do zidentyfikowania stosu wywołań, kiedy ustalono silne odniesienie (często pozwalając ci zidentyfikować dokładną linię kodu, w której ustalono te silne referencje). Aby uzyskać więcej informacji, zobacz wideo o WWDC 2016: Visual Debugging with Xcode.

Instrumentów można również używać do identyfikowania wycieków obiektów. Po prostu uruchom aplikację za pomocą Instrumentów za pomocą narzędzia Przydziały, nie tylko raz lub dwa razy, a następnie przywróć aplikację do stanu stabilnego, a jeśli pamięć nadal będzie się zwiększać, najprawdopodobniej uzyskasz mocny cykl odniesienia. Możesz użyć narzędzia Przydziały, aby określić, jakiego rodzaju obiekty nie są wydawane, użyj funkcji "licznika rekordów", aby dokładnie ustalić, gdzie zostały utworzone te silne referencje, itp.

Zobacz wideo z WWDC 2013 Fixing Memory Issues i WWDC 2012 wideo do wprowadzania do identyfikacji i rozwiązywania problemów z pamięcią. Podstawowe proponowane tam techniki są nadal aktualne (chociaż narzędzia UI Instruments zmieniły się nieco ... jeśli chcesz wprowadzić do lekko zmienionego interfejsu, zobacz WWDC 2014 wideo Improving Your App with Instruments).

Na marginesie "wywóz śmieci" odnosi się do bardzo odmiennego systemu pamięci i nie ma tu zastosowania.

1

bardzo proste podejście jest umieścić wydruk w deinitialiser

deinit { 
    print("<yourviewcontroller> destroyed.") 
} 

zapewnienia, że ​​widzisz tę linię coraz drukowane na konsoli. umieść deinit we wszystkich kontrolerach widoku. w przypadku, gdy nie byłeś w stanie zobaczyć konkretnego kontrolera viewcontroller, oznacza to, że jest to cykl odniesienia. Możliwe przyczyny są delegowane, zamknięcia zamykają się, nie są zapowiadane czasomierze itp.

+1

Do tego podejścia dodaję ręczne "wyszukiwanie binarne": wyłącz całą sekcję kodu i upewnij się, że wywoływana jest funkcja deinit. Ponownie włącz połowę kodu i sprawdź, czy deinit nadal jest wywoływany, a jeśli nie. Recurse;) – endavid

+0

W Swift, ponieważ tak łatwo jest tworzyć inline closures, istnieje również większe prawdopodobieństwo tworzenia cykli referencyjnych w nich. Miej oko na wszelkie zamknięcia w kodzie. Aby być bezpiecznym, zwykle rozpoczynam moje zamykanie ze strażnikiem [słabego ja] niech słabe Samuel = jaźń {powrot}. Przeczytaj https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-ID48 – endavid

16

Możesz dodawać funkcje deinit do swoich klas, które będą wywoływane, gdy obiekty zostaną zwolnione.

Jeśli deinit nie zostanie wywołany, gdy aplikacja jest uruchomiona, możesz nacisnąć przycisk Debug Memory Graph (zaznaczony poniżej) i sprawdzić, co ma odniesienie do czego.

Debug Memory Graph Button

Użyj menu rozwijanego u góry panelu środkowego, aby przełączać się pomiędzy klasami i wystąpień klas.

Jeśli coś jest przydzielane w kółko bez zwolnienia, powinieneś zobaczyć wiele instancji i powinieneś być w stanie zobaczyć za pomocą wykresu kierunkowego, jeśli jedno z jego dzieci ma silne odniesienie do rodzica.