La risposta è ... beh ... semplice. Semplicità e coerenza, infatti.
Objective-C è puramente dinamico al momento dell'invio del metodo. In particolare, ogni invio di metodo passa attraverso lo stesso identico punto di risoluzione del metodo dinamico di ogni altro invio di metodo. In fase di esecuzione, ogni implementazione del metodo ha la stessa identica esposizione e tutte le API fornite dal runtime Objective-C che funzionano con metodi e selettori funzionano allo stesso modo in tutti i metodi.
Come molti hanno risposto (sia qui che in altre domande), i metodi privati in fase di compilazione sono supportati; se una classe non dichiara un metodo nella sua interfaccia pubblicamente disponibile, allora quel metodo potrebbe anche non esistere per quanto riguarda il codice. In altre parole, puoi ottenere tutte le varie combinazioni di visibilità desiderate al momento della compilazione organizzando il tuo progetto in modo appropriato.
C'è poco vantaggio nel duplicare la stessa funzionalità nel runtime. Aggiungerebbe un'enorme quantità di complessità e overhead. E anche con tutta quella complessità, non impedirebbe a tutti, tranne che allo sviluppatore più casuale, di eseguire i tuoi metodi presumibilmente "privati".
EDIT: Uno dei presupposti che ho notato è che i messaggi privati dovrebbero passare attraverso il runtime con un conseguente sovraccarico potenzialmente grande. È assolutamente vero?
Sì. Non c'è motivo di supporre che l'implementatore di una classe non voglia utilizzare tutte le funzionalità Objective-C impostate nell'implementazione, e questo significa che deve avvenire l'invio dinamico. Tuttavia , non vi è alcun motivo particolare per cui i metodi privati non possano essere inviati da una variante speciale di objc_msgSend()
, dal momento che il compilatore saprebbe che sono privati; vale a dire, questo può essere ottenuto aggiungendo alla struttura una tabella di metodi solo privati Class
.
Non ci sarebbe modo per un metodo privato di cortocircuitare questo controllo o saltare il runtime?
Non potrebbe saltare il runtime, ma il runtime non dovrebbe necessariamente eseguire alcun controllo per i metodi privati.
Detto questo, non c'è motivo per cui una terza parte non possa chiamare deliberatamente objc_msgSendPrivate()
un oggetto, al di fuori dell'implementazione di quell'oggetto, e alcune cose (KVO, ad esempio) dovrebbero farlo. In effetti, sarebbe solo una convenzione e in pratica un po 'meglio che prefissare i selettori dei metodi privati o non menzionarli nell'intestazione dell'interfaccia.
Fare ciò, tuttavia, minerebbe la pura natura dinamica del linguaggio. Ogni invio di metodo non passerà più attraverso un meccanismo di invio identico. Invece, saresti lasciato in una situazione in cui la maggior parte dei metodi si comporta in un modo e una piccola manciata è semplicemente diversa.
Ciò si estende oltre il runtime poiché ci sono molti meccanismi in Cocoa costruiti sulla base del dinamismo coerente di Objective-C. Ad esempio, sia la codifica del valore chiave che l'osservazione del valore chiave dovrebbero essere modificate molto pesantemente per supportare metodi privati - molto probabilmente creando una scappatoia sfruttabile - o metodi privati sarebbero incompatibili.