Chcę użyć selektora na instancji NSObject bez potrzeby zaimplementowanego protokołu. Na przykład istnieje metoda kategorii, która powinna ustawić właściwość błędu, jeśli instancja NSObject, do której jest wywoływana, obsługuje ją. To jest kod, który działa zgodnie z przeznaczeniem:
if ([self respondsToSelector:@selector(setError:)])
{
[self performSelector:@selector(setError:) withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]];
}
Jednak kompilator nie widzi żadnej metody z setError: signature, więc wyświetla ostrzeżenie dla każdego wiersza zawierającego @selector(setError:)
fragment:
Undeclared selector 'setError:'
Nie chcę deklarować protokołu, aby pozbyć się tego ostrzeżenia, ponieważ nie chcę, aby wszystkie klasy, które mogą go używać, implementowały cokolwiek specjalnego. Chciałbym, żeby miały jakąś setError:
metodę lub właściwość.
Czy jest to wykonalne? W jaki sposób?
Pozdrawiam,
EP
objective-c
selector
categories
epologee
źródło
źródło
Odpowiedzi:
Inną opcją byłoby wyłączenie ostrzeżenia za pomocą:
Możesz umieścić ten wiersz w pliku .m, w którym pojawia się ostrzeżenie.
Aktualizacja:
Działa również z LLVM w następujący sposób:
źródło
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
// Do your thing
#pragma clang diagnostic pop
#pragma clang diagnostic ignored "-Wselector"
Spójrz na NSSelectorFromString .
Pozwoli to na utworzenie selektora w czasie wykonywania zamiast kompilacji za pomocą
@selector
słowa kluczowego, a kompilator nie będzie miał szans na narzekanie.źródło
sel_registerName()
wygląda na niejasną i taką, do której nie powinieneś dzwonić bezpośrednio, chyba że wiesz, co robisz, coś w rodzaju obj_msg_send ();)Myślę, że dzieje się tak, ponieważ z jakiegoś dziwnego powodu selektor nie jest zarejestrowany w środowisku wykonawczym.
Spróbuj zarejestrować selektor przez
sel_registerName()
:źródło
NSSelectorFromString
dzwonisel_registerName()
pod maską. Wybierz ten, który bardziej Ci odpowiada.sel_registerName()
bezpośrednie dzwonienie jest bardziej wyraźne, jeśli chodzi o to, dlaczego to robisz.NSSelectorFromString
nie mówi , że będzie próbował zarejestrować selektor.Otrzymałem ten komunikat, aby zniknął, # dołączając plik do metody. Nic innego nie zostało użyte z tego pliku.
źródło
Zdaję sobie sprawę, że trochę się spóźniłem z tym wątkiem, ale dla kompletności możesz globalnie wyłączyć to ostrzeżenie, używając docelowych ustawień kompilacji.
W sekcji „Ostrzeżenia Apple LLVM - Cel-C” zmień:
źródło
Jeśli twoja klasa implementuje metodę setError: (nawet poprzez zadeklarowanie dynamicznej metody ustawiającej ewentualną właściwość błędu), możesz chcieć zadeklarować ją w swoim pliku interfejsu (.h) lub jeśli nie lubisz pokazywać tego w ten sposób, możesz spróbuj z podstępną sztuczką PrivateMethods:
tuż przed Twoją @implementacją powinno to ukryć ostrzeżenia;).
źródło
PerformSelector may cause a leak because its selector is unknown
Naprawdę wygodne makro umieścić w swoim
.pch
lubCommon.h
czy gdziekolwiek chcesz:To edycja tego pytania w podobnym wydaniu ...
źródło
Możesz to wyłączyć w Xcode jak na zrzucie ekranu:
źródło
Możesz również najpierw rzutować obiekt na identyfikator, aby uniknąć ostrzeżenia:
źródło
Innym sposobem uniknięcia tego ostrzeżenia jest upewnienie się, że metoda selektora wygląda następująco:
Nie zapomnij o „(id) nadawca”, jeśli chcesz zaakceptować dowolnego nadawcę lub, jeśli wolisz, określić typ obiektu nadawcy.
źródło
Chociaż prawidłowa odpowiedź prawdopodobnie polega na poinformowaniu Xcode poprzez import lub zarejestrowanie selektora, że taki selektor istnieje, w moim przypadku brakowało średnika. Zanim „naprawisz” błąd, upewnij się, że być może błąd jest poprawny, a Twój kod nie. Znalazłem błąd na przykład w przykładzie Apple MVCNetworking.
źródło
Udało mi się uzyskać ostrzeżenie, aby odejść, dodając żadną metodę (ujawnienie: nie pomyślałem o tym, ale znalazłem to, wpisując w Google w zaplanowanym czasie z interwałem czasowym)
Chociaż doceniam to, że wiem, jak ukryć ostrzeżenie, naprawienie go jest lepsze, a techniki Sergio ani Relkin nie zadziałały dla mnie z nieznanych powodów.
źródło