Najlepszy sposób na uniemożliwienie innym programistom wywołania-init

Podczas projektowania hierarchii klas, czasami podklasa dodała nową metodę initWithSomeNewParam i pożądane byłoby wyłączenie wywołań starej metody init odziedziczonej po klasie nadrzędnej.

Po pierwsze, przeczytałem pytanie tutaj, gdzie proponowane alternatywy są albo nadpisywane init, aby rzucić wyjątek w czasie wykonywania, albo nadpisywane i ustawiane wartości domyślne dla właściwości. W moim przypadku nie chcę podawać wartości domyślnych i chcę wyraźnie zaznaczyć, że stare metoda nie powinna być wywoływana, a zamiast tego powinna zostać użyta nowa metoda z parametrami.

Więc wyjątek runtime jest w porządku, ale jeśli kod nie jest debugowany, nie ma sposobu, aby inni programiści w zespole zauważyli, że stara metoda nie jest już przeznaczona do użycia.

Jeśli się nie mylę, nie da się oznaczyć metody jako "prywatna". Czy oprócz dodawania komentarzy jest na to jakiś sposób? Z góry dzięki.
Author: Community, 2012-03-09

5 answers

Możesz wyraźnie zaznaczyć swoją init jako niedostępną w pliku nagłówkowym:

- (id) init __unavailable;

Lub:

- (id) init __attribute__((unavailable));

Z późniejszą składnią, możesz nawet podać powód:

- (id) init __attribute__((unavailable("Must use initWithFoo: instead.")));

Kompilator następnie wydaje błąd (nie ostrzeżenie), jeśli ktoś próbuje go wywołać.

 104
Author: DarkDust,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-22 20:27:28

Aby dodać to, co napisał @ DarkDust, możesz alternatywnie użyć UNAVAILABLE_ATTRIBUTE

- (id)init UNAVAILABLE_ATTRIBUTE;

Spowoduje to wyświetlenie błędu, gdy użytkownik spróbuje wywołać init na instancji tej klasy.

 4
Author: RileyE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-31 18:22:59

Flag it deprecated? Deweloperzy będą deweloperami, nie powstrzymasz nas wszystkich! ;-)

Jak oznaczyć metodę jako przestarzałą w Objective-C 2.0?

 1
Author: Jake,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:38

Initwith:Stuff I:OtherStuff nigdy nie powinny być więcej niż konstruktorami wygodnymi.

W tym, że skutecznie powinny wywoływać

self = [self init];

if(self)
{
    self.stuff = Stuff;
    self.other = OtherStuff;
}

Tak więc [object INIT] zawsze zwróci obiekt w predefiniowanym stanie, a [object initwithstuff: stuff] zwróci obiekt w predefiniowanym stanie z nadpisaniem stuff.

Zasadniczo do czego zmierzam, to zła praktyka zniechęcania [obiekt init] zwłaszcza, gdy ktoś podklasuje Twoją podklasę w przyszłości....

 0
Author: Tony Million,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-09 12:58:15

Możesz coś w rodzaju oznaczyć metodę jako "prywatną", definiując prywatne rozszerzenie do swojej klasy.

W Twoim .h:
@interface MyClassName
- (void)initWithSomeNewParam:(id)param;
W Twoim .m:
@interface MyClassName ()
- (void)init;
@end

Możesz również dodać NSLog, Aby gdy ktoś uruchomi projekt z dołączoną sesją XCode, zobaczy wyjście konsoli podobne do " proszę nie używać init, zamiast tego użyj initWithSomeNewParam:."Zauważ, że jest to podejście, które Apple w przeszłości stosowało do przestarzałych wywołań API (a także oznaczania deprecated in their docs).

 -1
Author: darvids0n,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-09 13:00:04