Domanda

Sto imparando Objective-C e ho uno sfondo C / C ++.

  • Nel C ++ orientato agli oggetti, è sempre necessario dichiarare il metodo prima di definirlo (implementarlo), anche se è dichiarato nella classe genitore.

  • In stile procedurale C, IIRC, puoi cavartela semplicemente definendo una funzione fintanto che viene chiamata solo da qualcos'altro nella stessa unità compilazionale (cioè lo stesso file) che è venuto successivamente in il file (beh, a condizione che non lo dichiari altrove con " extern ").

  • Ora, in Objective-C, sembra che devi dichiarare i selettori nel file di intestazione solo se saranno utilizzati da qualcosa di esterno e che puoi creare selettori nel tuo file .m solo bene, e chiamali nel file .m. Inoltre, sembra che i metodi delegati o ereditati non vengano mai (ri) definiti.

Sono sulla buona strada? Quando è necessario definire un selettore in Objective-C?

È stato utile?

Soluzione

Per i metodi Objective-C, la pratica generale è quella di mettere i metodi che si desidera esporre nella sezione @interface del file header in modo che altri codici possano includere solo il .h e sapere come interagire con il tuo codice. Dichiarazione pigra basata sull'ordine " funziona esattamente come le funzioni in C - non devi dichiarare un prototipo di metodo a meno che tu non abbia una dipendenza che non può essere risolta ordinando, ma puoi aggiungere prototipi di metodo all'interno di @ implementazione se necessario.

Quindi sì, sei sulla strada giusta. Non ripetere il prototipo del metodo per i metodi ereditati: il compilatore lo trova nel file di intestazione del genitore. I metodi delegati possono essere definiti come prototipi in una categoria (applicati a una classe) e implementati come desiderato, ma non è necessario che il delegato fornisca un prototipo di metodo, poiché è già definito. (Può ancora se vuole per chiarezza, ecc.)

Dato che stai solo imparando Objective-C, il resto di questa risposta è molto più dettagliato di quello che hai chiesto. Sei stato avvertito. ; -)


Quando digiti staticamente una variabile (ad es. MyClass * invece di id ) il compilatore ti avviserà quando provi a chiamare un metodo che una classe non pubblicizza che implementa, che lo faccia o no. Se digiti dinamicamente la variabile, il compilatore non ti impedirà di chiamare come preferisci e otterrai errori di runtime solo se chiami qualcosa che non esiste. Per quanto riguarda la lingua, puoi chiamare qualsiasi metodo implementato da una classe senza errori in fase di esecuzione - non c'è modo di limitare chi può chiamare un metodo.

Personalmente, penso che questa sia effettivamente una buona cosa. Ci abituiamo così tanto all'incapsulamento e alla protezione del nostro codice da altri codici che a volte trattiamo il chiamante come un deviante miscredente piuttosto che un fidato collaboratore o cliente. Trovo che sia abbastanza piacevole programmare con una mentalità di "fai il tuo lavoro e io faccio il mio" dove ognuno rispetta i confini e si prende cura delle proprie cose. Potresti dire che l'atteggiamento di "quotazione" di Objective-C è una questione di fiducia della comunità, piuttosto che di rigida applicazione. Ad esempio, sono felice di aiutare chiunque venga alla mia scrivania, ma sarei davvero infastidito se qualcuno facesse un casino con le mie cose o spostasse le cose senza chiedere. Il codice ben progettato non deve essere paranoico o sociopatico, deve solo funzionare bene insieme. : -)

Detto questo, ci sono molti approcci per strutturare le tue interfacce, a seconda del livello di granularità che desideri / necessiti nell'esporre le interfacce agli utenti. Qualsiasi metodo che dichiari nell'intestazione pubblica è essenzialmente un gioco equo da usare per chiunque. Nascondere le dichiarazioni dei metodi è un po 'come bloccare la tua auto o casa - probabilmente non terrà fuori tutti, ma (1) "mantiene oneste le persone oneste". non tentandoli con qualcosa con cui non dovrebbero scherzare e (2) chiunque entri in sicuramente saprà che non avrebbero dovuto farlo, e non può davvero lamentarsi delle conseguenze negative.

Di seguito sono riportate alcune convenzioni che utilizzo per la denominazione dei file e ciò che accade in ciascun file - a partire da un file .m in fondo, ogni file include quello sopra di esso. (L'uso di una rigida catena di inclusioni eviterà cose come avvisi di simboli duplicati.) Alcuni di questi livelli si applicano solo a componenti riutilizzabili più grandi, come i framework Cocoa. Adattali in base alle tue esigenze e usa i nomi che preferisci.

  • MyClass.h - API pubblica (Application Programming Interface)
  • MyClass_Private.h - SPI (interfaccia di programmazione del sistema) interna all'azienda
  • MyClass_Internal.h - IPI (Project Internal Interface) interno al progetto
  • MyClass.m - Implementazione, generalmente di tutte le dichiarazioni API / SPI / IPI
  • MyClass_Foo.m - Implementazione aggiuntiva, come per le categorie
L'API

è utilizzabile da tutti ed è supportata pubblicamente (di solito in Foo.framework / Headers ). SPI espone funzionalità aggiuntive per i client interni del tuo codice, ma con la consapevolezza che il supporto può essere limitato e l'interfaccia è soggetta a modifiche (di solito in Foo.framework / PrivateHeaders ). L'IPI consiste in dettagli specifici dell'implementazione che non dovrebbero mai essere utilizzati al di fuori del progetto stesso e queste intestazioni non sono affatto incluse nel framework. Chiunque scelga di utilizzare le chiamate SPI e IPI lo fa a proprio rischio e pericolo, in genere a svantaggio delle modifiche al proprio codice. : -)

Altri suggerimenti

La dichiarazione dei metodi nel file di intestazione interromperà solo gli avvisi del compilatore. Objective-C è un linguaggio dinamico, quindi puoi chiamare un metodo (inviare un messaggio) a un oggetto indipendentemente dal fatto che quel metodo sia dichiarato esternamente.

Inoltre, se si definisce un metodo nel file .m sopra qualsiasi codice che lo chiama (dichiarazione lazy), ciò non genererà alcun avviso. Comunque valga la stessa cosa, puoi inviare un messaggio a un oggetto senza che sia dichiarato.

Naturalmente - questo significa che non ci sono metodi privati ??in Objective-C. È possibile chiamare qualsiasi metodo implementato da una classe.

Preferenze personali. Se è un metodo pubblico (ovvero uno usato esternamente). dichiaralo in .h e definiscilo in .m. Se vuoi limitare la sua visibilità, o almeno indicare che si tratta di un metodo privato, usa categorie / estensioni di classe in. file m. Sebbene molti esempi di codice utilizzino il metodo di dichiarazione pigro.

Objective-C considera le funzioni come "messaggi" e come tale, puoi inviare un messaggio " " a qualsiasi oggetto, anche a uno che non afferma esplicitamente nella sua interfaccia che può accettare. Di conseguenza, non esistono cose come membri privati ??in Obj-C.

Questo può essere molto potente, ma è fonte di confusione per i nuovi programmatori Obj-C, in particolare quelli provenienti da C ++, Java o C #. Ecco le regole di base:

  • Dovresti definire tutti i metodi pubblici nella tua @interfaccia in modo che i consumatori sappiano quali messaggi ti aspetti di gestire.
  • Dovresti definire i metodi @private nella tua @interface per evitare i messaggi del compilatore ed evitare di dover ordinare i metodi nella tua @implementazione.
  • Dovresti usare i protocolli quando implementi una particolare convenzione di metodi per la tua classe.

Gran parte di questa è una preferenza personale, tuttavia aiuta a evitare fastidiosi avvisi del compilatore e mantiene organizzato il codice. e facile da capire.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top