• Non ci sono risultati.

Objective-C `e, come detto, il linguaggio preminente nell’ambiente Cocoa per lo sviluppo di applicazioni. Questo linguaggio `e un’estensione di ANSI-C in cui sono state introdotte caratteristiche sintattiche e semantiche4 che derivano da Smalltalk per includere nel linguaggio le astrazioni dell’object-oriented program- ming.

Tra le caratteristiche tipiche dei linguaggi di programmazione a oggetti esso presenta l’incapsulamento, l’ereditariet`a, la riusabilit`a e il polimorfismo, ma non sono disponibili l’ereditariet`a multipla, i template e l’overloading degli operatori (che invece sono presenti ad esempio in C++).

Un altra peculiarit`a di Objective C `e il dinamismo. Per quanto possibile, il linguaggio cerca di rinviare ogni decisione tipica della compilazione e del linking al runtime. Quindi al linguaggio non occorre soltanto un compilatore ma anche un

ambiente di runtime5. La determinazione della classe a cui appartiene un oggetto, ovvero il typing, avviene a runtime, cos`ı come il binding, ovvero la decisione di quale metodo eseguire, e il caricamento di moduli. In particolare, il typing pu`o avvenire a runtime utilizzando il tipo di dato id, descritto in Sezione A.3.1, per definire un generico oggetto la cui classe non sia ancora nota; ma il typing pu`o essere anche statico, specificando direttamente il tipo che la variabile dovr`a assumere. In questo modo, al compilatore `e concesso fare qualche controllo, come verificare se una classe implementa un certo metodo oppure no. Il compilatore per`o segnala questi eventuali problemi solo tramite warning.

A.3.1

Gli oggetti in Objective-C

In Objective-C ogni oggetto `e composto da dati e da operazioni che possono essere utilizzate per modificare questi dati. Essi vengono detti variabili di istanza (instance variables) e le operazioni sono dette metodi (di istanza). Esistono inol- tre i metodi di classe, che sono metodi non relativi ad una istanza specifica ma all’intera classe.

Le variabili di istanza non sono normalmente visibili all’esterno della classe, perci`o `e necessario implementare dei metodi di accesso ad esse utilizzando le pro- priet`a6. Di default, il livello di visibilit`a delle variabili di istanza `e @protected, perci`o `e visibile dalla classe stessa e da quelle che la estendono, ma `e possibile specificare anche altri livelli quali @private, @public e @package. Quest’ultimo livello equivale a una visibilit`a pari a @public dentro allo scope dell’immagine eseguibile della classe.

Per condividere variabili tra classi, occorre dichiararle fuori da una classe. Utilizzando la parola chiave static, `e possibile legare una variabile a una classe e utiilizzare dei metodi di classe per manipolarla. Una variabile statica non viene ereditata ed `e legata solo alla parte di classe definita nel file in cui la variabile `e dichiarata.

5Si veda [5], pag. 13 6Si veda Sezione A.3.2

Ogni classe viene dichiarata specificando un’interfaccia in un file del tipo ClassName.h e un’implementazione normalmente in un file ClassName.m.

Ogni oggetto mantiene un puntatore a se stesso di nome self. super, invece, `e un flag che segnala di cercare l’implementazione dei metodi nella superclasse.

All’interno dell’ambiente Cocoa, ogni oggetto discende dalla classe NSObject, formando una gerarchia. Questo vale sia per le classi definite dallo sviluppa- tore, sia per quelle presenti nei due framework di Cocoa, UIKit e Foundation. NSObject definisce l’interfaccia di base per ogni oggetto del linguaggio. A que- sto scopo, NSObject oltre che una classe `e anche un protocollo, per permettere di realizzare gerarchie di classi indipendenti ma che comunque siano conformi allo standard degli oggetti di questo framework. Ovviamente `e pi`u semplice mantene- re la classe NSObject come radice della propria gerarchia di classi, poich´e essa contiene gi`a tutti i meccanismi per il comportamento di un oggetto in quanto tale.

I metodi principali di questa classe sono:

alloc questo metodo alloca la memoria per l’oggetto e lo fa puntare alla classe di appartenenza.

init inizializza le variabili di istanza della classe.

class, superclass restituiscono un oggetto di tipo Class che identifica rispettiva- mente la classe di appartenenza e la superclasse dalla quale eredita la classe di cui l’oggetto `e istanza.

isKindOfClass, isMemberOfClass, isSubclassOfClass permettono di identifi- care a che classe appartiene l’oggetto in esame.

conformsToProtocol permette di verificare se una classe `e conforme a un certo protocollo7.

isEqual `e utilizzato per effettuare confronti tra oggetti.

description `e usato per associare una stringa di descrizione dell’oggetto.

forwardInvocation permette di inoltrare un messaggio ricevuto verso un altro oggetto.

performSelector `e un metodo utilizzato per inviare messaggi dopo un certo in- tervallo di tempo, e per scambiare messaggi tra thread.

Quando una nuova classe viene creata, essa deve essere definita come sotto- classe di un’altra classe esistente, a meno che non si stia definendo la classe radice di una nuova gerarchia.

In questo linguaggio, NSObject `e un esempio di classe astratta, ma in realt`a non esistono sintassi particolari per indicare che una classe non `e concreta, n´e impedisce la creazione di un’istanza di una classe astratta.

Ogni oggetto contiene una struttura dati. Il principale dato contenuto in esso `e il puntatore isa, che definisce di quale classe l’oggetto `e istanza. Esso collega l’oggetto alla classe di appartenenza puntando all’oggetto che definisce la classe, essendo la classe essa stessa un oggetto.

Le interazioni tra oggetti sono definite da uno scambio di messaggi tra gli stes- si. Un messaggio specifica il nome di un selettore, il quale serve per selezionare il metodo dell’oggetto da eseguire. Il concetto di nome di selettore, spesso chiamato per brevit`a selettore esso stesso, `e un tipo del linguaggio che si specifica con la parola chiave SEL. Oltre al selettore, il messaggio che viene inviato da un oggetto a un altro normalmente contiene anche una serie di parametri che si specificano insieme alla parola chiave che li definisce. Il tutto `e racchiuso tra parentesi quadre, con una struttura del tipo:

NSClassName *variable =

[ receiver selectorName:param1 keyword2:param2 ...]

In questo caso si prevede anche un valore di ritorno di tipo NSClassName, ma non `e necessario; il tipo di ritorno pu`o anche essere void.

Il selettore completo di questo messaggio sar`a selectorName:keyword2:... e cos`ı via, poich´e il nome del selettore comprende anche i nomi dei parametri e il simbolo : che separa il nome del parametro dal parametro stesso. Il nome del pri- mo parametro `e sottinteso e segue direttamente il nome del metodo. Se il metodo

non deve ricevere alcun parametro in ingresso, il nome completo del selettore sar`a semplicemente selectorName. Si parla perci`o di scambio di messaggi tra oggetti per indicare la chiamata a metodi.

Altri tipi di dato peculiari del linguaggio sono:

id `e un tipo di dato dinamico che pu`o contenere il riferimento a un oggetto di qualunque classe, in virt`u del tipying dinamico del linguaggio.

Class `e il tipo di dato che rappresenta una classe. Ogni classe `e istanza di tipo Class.

A.3.2

Estensioni in Cocoa

In Cocoa, il linguaggio presenta quattro tipi di estensioni che ne aumentano la potenza e la flessibilit`a.

Categories le categorie permettono di aggiungere metodi ad una classe senza farne il subclassing, `e perci`o un metodo alternativo all’ereditariet`a. Inoltre permettono di raggruppare i metodi in base al loro utilizzo, o per esigenze di sviluppo. Tutti i metodi aggiunti attraverso le categorie sono automa- ticamente ereditati dalle sottoclassi. Le categorie per`o non permettono di aggiungere variabili di istanza alla classe.

Protocols i protocolli sono un modo per definire una lista di metodi e propriet`a che un metodo pu`o scegliere o meno di implementare; in questo senso as- somigliano alle interfacce del linguaggio Java. Anche questo metodo pu`o essere un’alternativa al subclassing, permettendo di ovviare alla mancanza dell’ereditariet`a multipla, poich´e una classe pu`o adottare pi`u protocolli sen- za perdere la sua identit`a. I protocolli possono essere formali o informali. Nel primo caso la classe che adotta il protocollo deve obbligatoriamente im- plementare tutti i metodi definiti nel protocollo stesso; nel secondo caso pu`o scegliere quali metodi implementare. I protocolli permettono l’utilizzo di oggetti anonimi, rendendo effettivamente utile il typing dinamico, oltre ad

aggiungere la possibilit`a di mandare messaggi a oggetti di altre applicazioni, detti oggetti remoti.

Declared Properties l’utilizzo delle propriet`a permette di definire in automatico i metodi che forniscono l’accesso alle variabili di istanza delle classi8, ovvero setter e getter.

Fast Enumeration L’enumerazione rapida definisce una sintassi per il ciclo for apposita per l’iterazione di strutture dati quali array (NSArray), set (NSSet), ecc9.