Differenze tra messaggi e metodi?

13

In Objective C si ha il concetto di inviare messaggi ad altri oggetti e, beh, questo è molto simile al metodo che chiama in linguaggi come C # e Java.

Ma quali esattamente sono le sottili differenze? Come dovrei pensare ai messaggi quando pensi al mio codice?

Nota: solo un po 'di background qui, sono uno sviluppatore C # / Java che cerca di capire alcuni concetti sull'Obiettivo C.

    
posta Vidar 11.02.2011 - 12:26
fonte

5 risposte

10

Un messaggio è il nome di un selettore e i parametri per quel selettore.

Un selettore è un simbolo.

Un metodo è un pezzo di codice in una classe identificata da un selettore.

In altre parole, [foo bar: baz] dice "invia il messaggio chiamato @selector(bar:) con parametro baz all'oggetto foo . Potresti inviare quel messaggio a molti oggetti diversi.

Al contrario, il metodo bar: per un Foo potrebbe apparire come

-(int)bar:(int)n {
  return n + 1;
}

ma per un FooTwo potrebbe sembrare

-(int)bar:(int)n {
  return n + 2;
}

(spero di avere la sintassi giusta, è passato un po 'di tempo dall'ultima volta che ho toccato Objective-C.)

Quando invii il messaggio, il kernel Objective-C invia il messaggio a foo che decide se comprende il messaggio. Decide in base alla possibilità di trovare un metodo identificato da quel selettore.

Due metodi con lo stesso nome e un solo messaggio.

È anche possibile per un oggetto semplicemente inoltrare un particolare messaggio (o una serie di messaggi) a un altro oggetto per l'elaborazione. In questo caso, si invia un messaggio a questo oggetto proxy, che non ha metodi per abbinare quel messaggio e il proxy inoltra il messaggio al suo oggetto spostato.

    
risposta data 11.02.2011 - 14:00
fonte
3

Da un punto di vista puramente teorico, non c'è alcuna differenza tra i due - ci sono state un certo numero di dimostrazioni formali che dimostrano che i due sono completamente equivalenti e che possono essere implementati interamente in termini di altro.

Da un punto di vista leggermente meno teorico, c'è una differenza possibile: in un'implementazione tipica, la tabella delle funzioni virtuali viene allocata staticamente e il contenuto di ogni vtable è fissato in fase di compilazione. La ricerca di messaggi, al contrario, viene in genere eseguita con una sorta di oggetto simile a una mappa, che è in genere dinamico, il che significa che è possibile modificarlo in fase di runtime. Ciò rende relativamente facile aggiungere una nuova risposta a un messaggio in una classe esistente. Sfortunatamente, nella maggior parte dei casi questo rimane per lo più teorico. In primo luogo, si tratta essenzialmente di codice auto-modificante, che la maggior parte delle persone ha deciso è stata una pessima idea un lungo tempo fa. In secondo luogo, per renderlo molto significativo, è necessario essere in grado di compilare un nuovo codice nella classe esistente per rispondere al nuovo messaggio che si supporta. Senza quello, tutto ciò che ottieni è la capacità di aggiungere dinamicamente un nuovo nome per un metodo esistente.

Come implicito dalla fine del paragrafo precedente, da un punto di vista veramente pratico, c'è davvero poca differenza tra i due. Sono semplicemente due (molto leggermente) modi diversi per supportare l'associazione tardiva. Sebbene la ricerca basata sui messaggi sia generalmente un po 'più lenta, sarebbe piuttosto insolito che la differenza sia veramente significativa. Per scopi pratici, sono solo due modi diversi per realizzare la stessa cosa.

    
risposta data 11.02.2011 - 18:10
fonte
1

In Objective-C, i messaggi sono in ritardo. Cioè sono risolti in fase di runtime. C # supporta un costrutto simile attraverso la parola chiave Dynamic che dichiara anche un oggetto come tardivo.

    
risposta data 11.02.2011 - 13:59
fonte
0

Solitamente le chiamate al metodo vengono risolte in fase di compilazione (a meno che non si usi la reflection in Java), mentre i messaggi in Objective C vengono inviati in fase di runtime.

    
risposta data 11.02.2011 - 12:30
fonte
-1

I messaggi sono gestiti dal kernel o dal linguaggio stesso (per ObjC, ad esempio, c'è un codice assembly molto piccolo che lo fa).

Nel kernel di Linux, ad esempio, i messaggi vengono fatti con chiamate / funzioni di sistema: puoi trovarli su di essi se cerchi la programmazione del sistema unix.

La differenza principale tra una chiamata al metodo e un messaggio è questa:

  • una chiamata al metodo avviene solo nel tuo codice: in ASM è tradotta da un PUSH degli argomenti passati.

  • un messaggio del kernel è principalmente qualcosa inviato al kernel che viene tracciato e rinviato a determinati processi. Potrei scambiarli per pipe, ma qualunque cosa: sapere che esiste già un meccanismo che ti permette di eseguire più programmi contemporaneamente e di comunicare allo stesso tempo. Ovviamente, non sperare che funzioni allo stesso modo su Windows o su altri sistemi operativi.

risposta data 11.02.2011 - 13:48
fonte

Leggi altre domande sui tag