2017-07-25 44 views
13

Szukałem w narzędziu Xcode Memory Graph dla projektu i zauważyłem pewne dziwne zachowanie. Mam nadzieję, że ktoś będzie w stanie wyjaśnić, co się dzieje/jeśli muszę się martwić.Wykres pamięci debugowania Xcode pokazujący zwolniony obiekt

Mam kontroler widoku, który tworzy kilka obiektów (które obecnie niewiele nie robią). Po zwolnieniu kontrolera widoku na pewno zostaną zwolnione. Ale jedna (czasami oba) wydają się obijać w debuggera wizualnej:

enter image description here

tylko dwa są zawsze tworzone, a obie są już deinitialized, potwierdzone w moim konsolą:

enter image description here

Myślę, że mam rację mówiąc, nie jestem odpowiedzialny za żaden z obiektów odwołujących się do tego obiektu User na powyższym obrazku, więc czy jest to błąd, czy po prostu coś, o co nie muszę się martwić?

+0

nadal masz ten problem? –

Odpowiedz

0

Czy "zwolniony użytkownik" został zalogowany z metody deinit obiektu? Jeśli tak, to obiekty zostały deinicjowane, więc wszelkie odniesienia tam pokazujące nie były w stanie utrzymać obiektu przy życiu. Biorąc to pod uwagę, prawdopodobnie nie będę się tym przejmował, chociaż jeśli chcesz mieć pewność, najlepszą rzeczą do zrobienia jest odpalenie instrumentów, załadowanie narzędzia alokacji, kliknięcie przycisku Uruchom i zaznaczenie "Liczba rekordów referencyjnych . " Dzięki temu zobaczysz dokładnie, co zachowuje i zwalnia twoje obiekty.

1

Jeśli nie ponosisz odpowiedzialności za obiekty opisane na wykresie, które zachowują obiekt użytkownika, nie powinieneś się o to martwić.

FYI: Doświadczyłem przecieków przed włączeniem Firebase do aplikacji. To nie twoja wina i nie powinna przeciekać dużo wspomnienia.

Zgadzam się z @CharlesSrstka, jeśli nadal martwisz się o wycieki, możesz je również sprawdzić na instrumentach, gdzie pokaże ci konkretną linię kodu, która może być przyczyną problemu.

+0

dodaj to do swojego googleservice-info.plist FIREBASE_ANALYTICS_COLLECTION_ENABLED = NO prawdopodobnie zmniejszy wycieki –

0

Nie jestem pewien, czy to właśnie się z tobą dzieje, ale to mi się przydarzyło i okazało się, że jest to konsekwencja modelu pamięci wewnętrznej Swifta, a konkretnie, jak radzi sobie z słabymi i niezarejestrowanymi referencjami.

Aby to się do Ciebie odnosiło, coś musiało mieć słabe lub niezmienione odniesienie do twojego obiektu użytkownika.

W takim przypadku, po usunięciu ostatniego silnego odniesienia do obiektu, obiekt zostanie dezinicjowany - wszystko, co się do niego odniesie, będzie miało zmniejszoną liczbę odnośników i zostanie zwolnione w razie potrzeby, a jego metoda deinit() zostanie uruchom (jak pokazują twoje logi). Jednak nie zostanie on zdekallocated deallocated.

Tak, obiekt można zdezynfekować, ale nie zwolnić! Powodem tego jest to, że słabe lub niezmienione odniesienie tego punktu na tym obiekcie nie może wskazywać na zwolnioną (lub gorzej przydzieloną) pamięć, ponieważ podążanie za tym wskaźnikiem powodowałoby "niebezpieczne" zachowanie. W rezultacie ta część pamięci nie może zostać zrezygnowana, a zatem obiekt nie jest zwolniony.

Jednak dwie dobre wiadomości. Po pierwsze, przecieka tylko ten konkretny obiekt - żaden z obiektów, do których się odwołuje. Oznacza to, że wycieka tylko niewielka część pamięci. To może nie być wielka sprawa. Po drugie, w przypadku słabych referencji, zachowanie to zostało zmienione w Swift 4 (niestety referencje bez właściciela nadal będą miały takie zachowanie).Ciekawie byłoby wypróbować swój projekt w wersji beta Xcode9 i sprawdzić, czy nadal się dzieje.

To wszystko polega na zadawaniu tego samego pytania w WWDC. Mam nadzieję, że okaże się to możliwe!

+0

Dzięki za wnikliwą odpowiedź. W tym przypadku nie wydaje mi się, aby jakiekolwiek słabe lub niezarejestrowane referencje miały miejsce. W rzeczywistości stworzyłem całkowicie pusty projekt, aby ten przykład mógł replikować zachowanie. Wszystko, co było w projekcie, to w zasadzie pusta klasa "User" i "ViewController". Zakończyły się tymi wynikami. Dzięki i tak. –