Odpowiedź jest ... cóż ... prosta. A właściwie prostota i konsekwencja.
Cel-C jest czysto dynamiczny w momencie wysyłania metody. W szczególności, każda wysyłka metody przechodzi przez dokładnie ten sam dynamiczny punkt rozwiązania metody, co każda inna wysyłka metody. W czasie wykonywania każda implementacja metody ma dokładnie taką samą ekspozycję, a wszystkie interfejsy API dostarczane przez środowisko wykonawcze Objective-C, które współpracują z metodami i selektorami, działają tak samo we wszystkich metodach.
Jak wielu odpowiedziało (zarówno tutaj, jak i w innych pytaniach), obsługiwane są prywatne metody kompilacji; jeśli klasa nie deklaruje metody w swoim publicznie dostępnym interfejsie, to ta metoda równie dobrze może nie istnieć, jeśli chodzi o Twój kod. Innymi słowy, możesz osiągnąć wszystkie różne kombinacje widoczności pożądane w czasie kompilacji, odpowiednio organizując projekt.
Duplikowanie tej samej funkcjonalności w środowisku wykonawczym nie przynosi większych korzyści. Dodałoby to ogromną złożoność i narzut. I nawet przy całej tej złożoności, nadal nie przeszkodziłoby to wszystkim, z wyjątkiem najbardziej przypadkowego programisty, w wykonywaniu twoich rzekomo „prywatnych” metod.
EDYCJA: Jednym z założeń, które zauważyłem, jest to, że prywatne wiadomości musiałyby przejść przez środowisko wykonawcze, co spowodowałoby potencjalnie duży narzut. Czy to absolutna prawda?
Tak to jest. Nie ma powodu, by przypuszczać, że osoba implementująca klasę nie chciałaby używać wszystkich funkcji celu-C w implementacji, a to oznacza, że musi nastąpić dynamiczne wysyłanie. Jednak nie ma żadnego szczególnego powodu, dla którego metody prywatne nie mogłyby zostać wysłane przez specjalny wariant programu objc_msgSend()
, skoro kompilator wiedziałby, że są one prywatne; tj. można to osiągnąć poprzez dodanie do Class
struktury tabeli metod wyłącznie prywatnych .
Nie byłoby sposobu, aby prywatna metoda spowodowała zwarcie tego sprawdzenia lub pominięcie środowiska wykonawczego?
Nie może pominąć środowiska wykonawczego, ale środowisko wykonawcze niekoniecznie musiałoby sprawdzać metody prywatne.
To powiedziawszy, nie ma powodu, dla którego strona trzecia nie mogłaby celowo wywołać objc_msgSendPrivate()
obiektu poza implementacją tego obiektu, a niektóre rzeczy (na przykład KVO) musiałyby to zrobić. W efekcie byłaby to po prostu konwencja i niewiele lepsza w praktyce niż umieszczanie przedrostków selektorów metod prywatnych lub nie wspominanie ich w nagłówku interfejsu.
Jednak takie postępowanie podważyłoby czystą dynamiczną naturę języka. Nie każda wysyłka metodą będzie już przechodzić przez identyczny mechanizm. Zamiast tego zostałbyś pozostawiony w sytuacji, w której większość metod zachowuje się w jeden sposób, a kilka jest po prostu innych.
Wykracza to poza środowisko wykonawcze, ponieważ w kakao jest wiele mechanizmów opartych na konsekwentnej dynamice Objective-C. Na przykład zarówno kodowanie wartości klucza, jak i obserwacja wartości klucza musiałyby zostać bardzo mocno zmodyfikowane, aby obsługiwały metody prywatne - najprawdopodobniej poprzez utworzenie luki, którą można wykorzystać - albo metody prywatne byłyby niekompatybilne.