Jak mogę uniknąć tego ostrzeżenia w xcode. Oto fragment kodu:
[player(AVPlayer object) addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(0.1, 100)
queue:nil usingBlock:^(CMTime time) {
current+=1;
if(current==60)
{
min+=(current/60);
current = 0;
}
[timerDisp(UILabel) setText:[NSString stringWithFormat:@"%02d:%02d",min,current]];///warning occurs in this line
}];
objective-c
cocoa-touch
automatic-ref-counting
avplayer
retain
użytkownik1845209
źródło
źródło
timerDisp
nieruchomość jest w klasie?player(AVPlayer object)
itimerDisp(UILabel)
?Odpowiedzi:
Przechwytywanie
self
tutaj nadchodzi z twoim niejawnym dostępem do właściwościself.timerDisp
- nie możesz odwoływać się doself
właściwościself
z bloku, który zostanie mocno zatrzymanyself
.Możesz obejść ten problem, tworząc słabe odniesienie
self
przed dostępemtimerDisp
do bloku:źródło
__unsafe_unretained
zamiast tego.self
, jest utrzymywany przez główną kolejkę wysyłkową. Czy się mylę?I jedną bardzo ważną rzecz do zapamiętania: nie używaj zmiennych instancji bezpośrednio w bloku, użyj jej jako właściwości słabego obiektu, przykład:
i nie zapomnij zrobić:
inny problem może pojawić się, jeśli przekażesz słabą kopię nie zatrzymanego przez nikogo obiektu:
jeśli
vcToGo
zostanie zwolniony, a następnie ten blok zostanie uruchomiony, wierzę, że nastąpi awaria z nierozpoznanym selektorem do kosza, któryvcToGo_
teraz zawiera zmienną. Spróbuj to kontrolować.źródło
Lepsza wersja
Cała sprawa wyglądałaby tak:
Przeczytałem ten artykuł wiele razy. To jest doskonały artykuł Erici Sadun na temat unikania problemów podczas korzystania z bloków i NSNotificationCenter
Szybka aktualizacja:
Na przykład w trybie szybkim prostą metodą z blokiem sukcesu byłoby:
Kiedy wywołujemy tę metodę i trzeba jej użyć
self
w bloku sukcesu. Będziemy używać funkcji[weak self]
iguard let
.Ten tak zwany silny i słaby taniec wykorzystywany jest w popularnym projekcie open source
Alamofire
.Aby uzyskać więcej informacji, zapoznaj się z przewodnikiem po szybkim stylu
źródło
typeof(self) strongSelf = self;
poza blokiem (zamiast __weak), to w bloku powiedziałstrongSelf = nil;
po użyciu? Nie widzę, jak twój przykład zapewnia, że słabySelf nie jest zerowy do czasu wykonania bloku.W innej odpowiedzi Tim powiedział:
To nie do końca prawda. Możesz to robić, dopóki w pewnym momencie przerwiesz cykl. Załóżmy na przykład, że masz timer, który strzela, który ma blok, który zachowuje siebie, a także masz silne odniesienie do timera w sobie. Jest to całkowicie w porządku, jeśli zawsze wiesz, że w pewnym momencie zniszczysz stoper i przerwiesz cykl.
W moim przypadku miałem teraz ostrzeżenie dla kodu, który:
Teraz zdaję sobie sprawę, że clang wygeneruje to ostrzeżenie tylko wtedy, gdy wykryje, że metoda zaczyna się od „set” (i jeszcze jednego specjalnego przypadku, o którym nie wspomnę tutaj). Dla mnie wiem, że nie ma niebezpieczeństwa wystąpienia pętli zatrzymania, więc zmieniłem nazwę metody na „useY:” Oczywiście, może to nie być odpowiednie we wszystkich przypadkach i zwykle będziesz chciał użyć słabego odniesienia, ale Pomyślałem, że warto zwrócić uwagę na moje rozwiązanie na wypadek, gdyby pomogło innym.
źródło
Wiele razy tak naprawdę nie jest to cykl przechowywania .
Jeśli wiesz, że tak nie jest, nie musisz wprowadzać na świat bezowocnych słabych Samotnych.
Apple nawet wymusza na nas te ostrzeżenia za pomocą interfejsu API
UIPageViewController
, który obejmuje ich ustawioną metodę (która wyzwala te ostrzeżenia - jak wspomniano w innym miejscu - myśląc, że ustawiasz wartość dla ivar, który jest blokiem) i blok obsługi zakończenia (w którym bez wątpienia będziesz odnosić się do siebie).Oto kilka dyrektyw kompilatora, aby usunąć ostrzeżenie z tego jednego wiersza kodu:
źródło
Dodanie dwóch centów za poprawę precyzji i stylu. W większości przypadków użyjesz tylko jednego lub kilku członków
self
w tym bloku, najprawdopodobniej tylko w celu aktualizacji suwaka. Castingself
to przesada. Zamiast tego lepiej jest być jawnym i rzucać tylko te obiekty, których naprawdę potrzebujesz w bloku. Na przykład, jeśli jest to przykładUISlider*
, powiedzmy,_timeSlider
wykonaj następujące czynności przed deklaracją bloku:Następnie wystarczy użyć
slider
wewnątrz bloku. Technicznie jest to bardziej precyzyjne, ponieważ zawęża potencjalny cykl zatrzymania tylko do potrzebnego obiektu, a nie do wszystkich obiektów w środkuself
.Pełny przykład:
Dodatkowo, najprawdopodobniej obiekt rzucany na słaby wskaźnik jest już wewnątrz słabym wskaźnikiem,
self
a także minimalizuje lub całkowicie eliminuje prawdopodobieństwo cyklu zatrzymania. W powyższym przykładzie_timeSlider
właściwość jest przechowywana jako słaby odnośnik, np .:Pod względem stylu kodowania, podobnie jak w C i C ++, deklaracje zmiennych lepiej czytać od prawej do lewej. Deklarowanie
SomeType* __weak variable
w tej kolejności brzmi bardziej naturalnie od prawej do lewej, jak:variable is a weak pointer to SomeType
.źródło
Niedawno natrafiłem na to ostrzeżenie i chciałem je trochę lepiej zrozumieć. Po kilku próbach i błędach odkryłem, że pochodzi ona od tego, że metoda zaczyna się od „dodaj” lub „zapisz”. Cel C traktuje nazwy metod zaczynające się od „nowy”, „przydziel” itp. Jako zwracający zachowany obiekt, ale nie wspomina (że mogę znaleźć) niczego o „dodawaniu” lub „zapisywaniu”. Jeśli jednak użyję nazwy metody w ten sposób:
Zobaczę ostrzeżenie na linii [self done]. Nie spowoduje to jednak:
Pójdę naprzód i użyję metody „__weak __typeof (self) poorSelf = self”, aby odwołać się do mojego obiektu, ale tak naprawdę nie lubię tego robić, ponieważ to dezorientuje przyszłego mnie i / lub innego programistę. Oczywiście nie mogłem również użyć „dodaj” (lub „zapisz”), ale to gorzej, ponieważ odbiera to znaczenie tej metody.
źródło