Ecco a voi un altro estratto dal manuale Cocoa programming for Mac OS X, terza edizione, di Aaron Hillegass. La citazione riguarda il paragrafo sul messagging, ovvero quel che accade quando viene chiamato un metodo di una classe figlia di NSObject.
Come menzionato prima, un oggetto è simile a una struttura del C. NSObject dichiara una variabile d’istanza detta isa e, siccome NSObject è la radice dell’intero albero gerarchico della classe, ogni oggetto ha un puntatore isa alla struttura della classe che ha creato l’oggetto.
La struttura della classe include sia il nome e i tipi delle variabili d’istanza per quella classe, che l’implementazione dei metodi della classe stessa. Tale struttura ha un puntatore alla struttura della classe della superclasse.
I metodi sono indicizzati da un selettore di tipo SEL ma, nonostante SEL sia definito come char *, è più intuitivo pensare ad esso come a un intero. Il nome di ogni metodo viene quindi associato (mappato) ad un numero intero univoco (un integer). Per esempio, il nome del metodo addObject: potrebbe essere associato al numero 12, così quando utilizzerai dei metodi, userai il selettore e non la stringa @”addObject:”.
Esiste quindi una tabella, parte delle strutture dati dell’Objective-C, che mappa i nomi dei metodi ai corrispettivi selettori, come mostrato in figura 3.16.
Durante la compilazione, ogni volta che il compilatore riceve una chiamata a messaggio, consulta tale tabella. Ad esempio, la seguente chiamata:
[myObject addObject:yourObject];diventa (posto che il selettore per addObject: sia 12)
objc_msgSend(myObject, 12, yourObject);objc_msgSend() valuta il puntatore isa di myObject per arrivare alla struttura della sua classe e cerca il metodo associato al numero 12. Se non lo trova, segue il puntatore alla sua superclasse, e se anche la superclasse non ha il metodo associato al numero 12, allora continua a cercare ripercorrendo l’albero gerarchico. Se raggiunge la cima senza trovare alcun metodo, la funzione restituisce un’eccezione.
Questo è chiaramente un modo molto dinamico di maneggiare e gestire i messaggi. Le strutture delle classi possono essere modificate durante l’esecuzione utilizzando, ad esempio, la classe NSBundle, che rende rende relativamente semplice l’aggiunta di classi e metodi al programma mentre è in esecuzione. Questa potente tecnica è stata utilizzata per creare aplicazioni che possono essere estese da altri sviluppatori.
Here’s another extract from Cocoa programming for Mac OS X, third edition, wrote by Aaron Hillegass. Here’s an explanation about messaging between Cocoa classes.
As mentioned earlier, an object is like a C struct. NSObject declares an instance variable called isa. Because NSObject is the root of the entire class-inheritance tree, every object has an isa pointer to the class structure that created the object.
The class structure includes the names and types of the instance variables for the class, as well as the implementation of the class’s methods. The class structure has a pointer to the class structure for its superclass.
The methods are indexed by the selector. The selector is of type SEL. Although SEL is defined to be char *, it is most useful to think of it as an int. Each method name is mapped to a unique int. For example, the method name addObject: might map to the number 12. When you look up methods, you will use the selector, not the string @”addObject:”.
As part of the Objective-C data structures, a table maps the names of methods to their selectors. Figure 3.16 shows an example.
At compile time, the compiler looks up the selectors wherever it sees a message send. Thus,
[myObject addObject:yourObject];becomes (assuming that the selector for addObject: is 12)
objc_msgSend(myObject, 12, yourObject);Here, objc_msgSend() looks at myObject’s isa pointer to get to its class structure and looks for the method associated with 12. If it does not find the method, it follows the pointer to the superclass. If the superclass does not have a method for 12, it continues searching up the tree. If it reaches the top of the tree without finding a method, the function throws an exception.
Clearly, this is a very dynamic way of handling messages. These class structures can be changed at runtime. In particular, using the NSBundle class makes it relatively easy to add classes and methods to your program while it is running. This very powerful techniques has been used to create applications that can be extended by other developers.



