Piszę API, które obejmuje obsługę zdarzeń, i chciałbym móc używać bloków do obsługi. Połączenia zwrotne często chcą mieć dostęp lub modyfikować siebie. W trybie ARC, Klang ostrzega, że bloki odnoszące się do siebie prawdopodobnie stworzą cykl zachowywania, który wydaje się pomocnym ostrzeżeniem, które ogólnie chcę zachować.Kompaktowe wyłączenie ostrzeżenia o cyklach zatrzymywania łuku dla samoreferencyjnych bloków
Jednak w przypadku tej części interfejsu API cykl życia wywołania zwrotnego i obiektu zawierającego są utrzymywane na zewnątrz. Wiem, że mogę przerwać cykl, gdy obiekt powinien zostać zwolniony.
Mogę wyłączyć ostrzeżenie o cyklu zatrzymywania na podstawie pliku z #pragma clang diagnostic ignored "-Warc-retain-cycles"
, ale to wyłącza ostrzeżenie dla całego pliku. Mogę otoczyć bloki z ostrzeżeniem #pragma clang diagnostic push
i pop
, ale to sprawia, że bloki są brzydkie.
Mogę też otrzymać ostrzeżenie, aby odejść, odwołując się do zmiennej __weak wskazującej na siebie, zamiast bezpośrednio odnosić się do siebie, ale to sprawia, że bloki są o wiele mniej przyjemne w użyciu.
Najlepszym rozwiązaniem mam wymyślić jest to makro, które zrobi wyłączenie diagnostyczne wokół bloku:
#define OBSERVE(OBJ, OBSERVEE, PATH, CODE) \
[(OBJ) observeObject:(OBSERVEE) forKeyPath:(PATH) withBlock:^(id obj, NSDictionary *change) { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Warc-retain-cycles\"") \
do { CODE; } while(0); \
_Pragma("clang diagnostic pop") \
}];
który działa, ale nie jest to bardzo wykrywalne dla użytkowników API, nie pozwala zagnieżdżone obserwatorów, i źle współpracuje z edytorem XCode. Czy istnieje lepszy sposób na wyłączenie lub uniknięcie ostrzeżenia?
Tworzenie odwołania '__weak' do' self' dosłownie zajmuje jedną linię kodu. Myślę, że naprawienie problemu w tym przypadku jest lepsze niż próba złagodzenia objawów. W jaki sposób odwołanie się do 'weakSelf' zamiast' self' czyni blok mniej przyjemnym w użyciu? –
Jest mniej przyjemny na kilka sposobów. Słuchacze często są dość krótcy, czasami pojedynczy komunikat. Deklaracja __weak podwaja rozmiar słuchacza. Oznacza to również, że musisz kwalifikować dostęp do nieruchomości, zamiast używać wywnioskowanego siebie. Zgodzę się, że moje obecne rozwiązanie jest prawdopodobnie gorsze niż użycie __weak, ale miałem nadzieję, że dzięki temu pytaniu otrzymam lepszą. –
Czy możesz zmienić prototyp swojego bloku ukończenia, aby zaakceptować argument "własny"? Teraz kod, w którym przekazujesz swoje bloki będzie wyglądał tak samo (z wyjątkiem przyjmowania jednego dodatkowego argumentu) i możesz wyeliminować ostrzeżenia. (tzn. czy twój interfejs API przekazuje przedmiot do twojego bloku) – nielsbot