Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto...

188
Facoltà di Ingegneria Corso di Studi in Ingegneria Informatica tesi di laurea Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS Anno Accademico 2007/2008 relatore Ch.mo prof. Domenico Cotroneo correlatore Ch.mo prof. Marcello Cinque candidato Diomede Mazzone matr. 041/002515

Transcript of Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto...

Page 1: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Facoltà di Ingegneria Corso di Studi in Ingegneria Informatica tesi di laurea

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

Anno Accademico 2007/2008

relatore Ch.mo prof. Domenico Cotroneo correlatore Ch.mo prof. Marcello Cinque candidato Diomede Mazzone matr. 041/002515

Page 2: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti
Page 3: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

“Tutti gli esseri umani nascono liberi ed eguali in dignità e diritti. Essi sono dotati di ragione e di coscienza e devono agire gli uni verso gli altri in spirito di fratellanza.”

Dichiarazione Universale dei diritti Umani 60° anniversario 10 dicembre 1948-2008

...che sia la stella polare di ogni azione.

Page 4: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Indice

Introduzione 8

Capitolo 1 Sistemi operativi per dispositivi mobili 12

1.1. SISTEMA OPERATIVO SYMBIAN 13 1.2. SISTEMA OPERATIVO WINDOWS MOBILE 16 1.3. SISTEMA OPERATIVO ANDROID 17 1.4. SISTEMA OPERATIVO IPHONE OS 20

Capitolo 2 Struttura del sistema operativo iPhone OS 21

2.1. STRATIFICAZIONE 21 2.2 COCOA TOUCH 21 2.3 MEDIA 22 2.3.1 TECNOLOGIE GRAFICHE 22 2.3.2 TECNOLOGIE AUDIO 24 2.3.3 TECNOLOGIE VIDEO 25 2.4 CORE SERVICES 25 2.4.1 ADDRESS BOOK 25 2.4.2 CORE FOUNDATION 26 2.4.3 CORE LOCATION 27 2.4.4 CFNETWORK 27 2.4.5 SECURITY 28 2.4.6 SQLITE 28 2.4.7 XML SUPPORT 28 2.5 CORE OS 28 2.5.1 XNU 29 2.5.1.1 Mach 30 2.5.1.2 BSD 31 2.5.1.3 Standard I/O (I/O-Kit) 33 2.5.2 INTER PROCESS COMUNICATION (IPC) 33

Page 5: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

2.5.2.1 Task e Thread 33 2.5.2.2 Porte 36 2.5.2.3 Messaggi 37 2.5.3 BONJOUR E SERVIZI DNS 38 2.5.4 PROTEZIONE DELLE RISORSE CONDIVISE 38

Capitolo 3 Strumenti di sviluppo per iPhone 39

3.1 INTRODUZIONE ALL'AMBIENTE COCOA 39 3.1.1 COCOA IN MAC OS X 40 3.1.2 COCOA IN IPHONE OS 44 3.2 AMBIENTE DI SVILUPPO 46 3.2.1 PIATTAFORMA SDK 47 3.2.2 XCODE 47 3.2.3 FLUSSO DI LAVORO 48 3.2.4 INTERFACE BUILDER 49 3.2.5 THE IPHONE OS SIMULATOR 53 3.2.6 PRESTAZIONI DELLE APPLICAZIONI E TOOL 53 3.2.6.1 Instruments 53 3.2.6.2 Shark 54 3.2.6.3 Altre applicazioni per le prestazioni (Mac OS X) 55 3.3 COCOA FRAMEWORK 56 3.3.1 FOUNDATION 57 3.3.1.1 Foundation: paradigmi e politiche 58 3.3.1.2 Classi Foundation 59 3.3.2 APPLICATION KIT (MAC OS X) 66 3.3.2.1 Descrizione di Application Kit 67 3.3.2.2 Classi generali per le interfacce utenti 69 3.3.2.3 Testo e caratteri 71 3.3.2.4 Grafica e colori 72 3.3.2.5 Stampe e Fax 73 3.3.2.6 Documenti e supporto al File-System 73 3.3.2.7 Internazionalizzazione e Character Input Support 73 3.3.2.8 Operating-System Services 74 3.3.2.9 Interface Builder Support 74 3.3.3 UIKIT (IPHONE OS) 74 3.3.3.1 Descrizione delle classi di UIKit 75 3.3.3.2 Application Coordination 76 3.3.3.3 Differenze di modelli nei disegni e negli eventi 76 3.3.3.4 Classi generali dell'interfaccia utente 77

Page 6: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

3.3.3.5 Testo ed immagini 79 3.3.4 COMPARAZIONE TRA CLASSI DI APPLICATION KIT E UIKIT 79 3.4 PUBBLICAZIONE DI SOFTWARE 83 3.4.1 IPHONE DEVELOPER PROGRAM 84

Capitolo 4 Linguaggio di programmazione Objective-C 86

4.1 CENNI STORICI OBJECTIVE-C 86 4.2 PROGRAMMA DI ESEMPIO “HELLO, WORLD!” 87 4.2.1 Oggetti, Classi, metodi ed Istanze 90 4.2.2 Ereditarietà 92 4.2.3 Implementazione 92 4.2.4 Messaggi e polimorfismo 95 4.2.5 Scomporre il codice in più file 96 4.2.6 ELEMENTI COMUNI AL C 96 4.2.6.1 Tipi di dato 96 4.2.6.2 Funzioni 98 4.2.6.3 Costrutti 99 4.3 OBJECTIVE-C E OGGETTI COCOA 100 4.3.1 I VANTAGGI DI OBJECTIVE-C 101 4.3.2 DINAMICITÀ DI OBJECTIVE-C 102 4.3.3 LA CLASSE ROOT 104 4.3.3.1 NSObject 105 4.3.3.2 Classe root e Protocolli 105 4.3.3.3 Descrizione dei metodi della classe di root 106 4.3.3.4 Metodi di Classe e metodi di istanza 108 4.3.4 ALLOCAZIONE E RILASCIO DI OGGETTI 109 4.3.4.1 Memory management 110 4.3.5 ARCHIVIAZIONE DI OGGETTI 115 4.3.6 USARE OBJECTIVE 116 4.4 OBJECTIVE-C: ASPETTI AVANZATI 120 4.4.1 CATEGORIE 121 4.4.2 PROTOCOLLI 122 4.4.3 DICHIARAZIONE DELLE PROPRIETÀ 127 4.4.4 FAST ENUMERATION 130 4.4.5 SELECTOR 132 4.4.6 CREAZIONE DI OGGETTI 132 4.4.6.1 Allocazione 133 4.4.6.2 Inizializzazione 134 4.4.6.3 I metodi dealloc e finalize 144

Page 7: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

4.4.6.4 Metodi costruttori di classe 146 4.4.7 INTROSPECTION 147 4.4.7.1 Valutazione dei rapporti gerarchici 147 4.4.7.2 Implementazione di metodi e conformità ai protocolli 149 4.4.7.3 Comparazione di oggetti 149 4.4.8 OGGETTI MODIFICABILI 150 4.4.9 RAGGRUPPAMENTO DI CLASSI 153 4.4.9.1 Struttura gerarchica 153 4.4.9.2 Creare istanze 154 4.4.9.3 Raggruppamento di classi con molteplici superclassi pubbliche 154

Capitolo 5 Presentazione di un caso di studio 157

5.1 PROGETTAZIONE 157 5.2 IMPLEMENTAZIONE 163 5.2.1 EAT&PHONEAPPDELEGATE 163 5.2.2 MAINVIEWCONTROLLER 164 5.2.3 MYCLCONTROLLER 171 5.3 SNAPSHOT DELL'APPLICAZIONE 179

Conclusioni 184

Bibliografia 188

Page 8: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

8

Introduzione

Negli ultimi decenni i dispositivi mobili hanno conquistato fette di mercato sempre più

rilevanti. Risulta evidente l'incremento di funzionalità che hanno subito dalla prima

generazione fino agli ultimi modelli, che includono in sé funzionalità che fino a poco

tempo fa erano supportate da diversi dispositivi dedicati. Con lo sviluppo di hardware

sempre più sofisticato è stato possibile quindi fornire tali dispositivi di caratteristiche

anche complesse. I cellulari di ultima generazione includono infatti supporto per l'ascolto

di file musicali, riproduzione video, collegamento ad internet tramite rete Wi-Fi,

funzionalità GPS ed alcuni dispositivi anche la possibilità di accedere alla rete televisiva.

Essendo prodotti così versatili, è intuibile quanto siano diventati presenti nelle abitudini

dei consumatori. Tale processo ha influito sia nelle abitudini degli stessi sia nelle scelte

commerciali dei produttori. Con il crescere delle prestazioni hardware infatti sono

cresciuti anche gli investimenti nel software che li sfrutta. I sistemi operativi per questi

sistemi infatti devono far fronte alle carenze hardware che tali dispositivi hanno rispetto ai

sistemi tradizionali, oltre a dover gestire interfacce utente notevolmente semplificate,

considerando gli schermi di ridotte dimensioni. Aziende del settore telefonico e produttori

di dispositivi mobili hanno così elaborato alcuni approcci commerciali per venire incontro

alle esigente dei consumatori. Le prospettive future vedono l'accesso ad internet non più

come una caratteristica aggiuntiva per i cellulari, ma un requisito importante per molti

utenti. Si intuisce così l'importanza per un produttore di dispositivi mobili di intercettare

questa esigenza e trovare soluzioni ottimali per una fascia sempre più ampia di

consumatori.

Considerando il panorama commerciale a cui si fa riferimento, le proposte dei vari

produttori quindi si differenziano sia per supporti hardware che per sistemi operativo

implementati. Altra classificazione possibile nelle offerte commerciali, riguarda la libertà

concessa a sviluppatori di terze parti di distribuire software dedicato alle specifiche

Page 9: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

9

piattaforme.

Nello studio che segue si è approfondito il dispositivo mobile proposto da Apple. Dal

punto di vista commerciale tale dispositivo mobile ha generato una piccola rivoluzione nel

settore, in quanto a pochi mesi dal suo lancio in quasi tutti i paesi del mondo, ha già

conquistato l'attenzione del mercato. L'11 luglio 2008 infatti la Apple ha lanciato la

seconda versione dell'iPhone, precedentemente commercializzato soltanto in alcuni Paesi.

Tale dispositivo è risultato di un tale successo che i principali dispositivi mobili, sviluppati

successivamente, vengono etichettati come “anti-iPhone”. Un caso eclatante è stato

Android, piattaforma software promossa da Google, che cerca con un approccio

commerciale antitetico di porsi come principale concorrente all'iPhone stesso. È chiaro

infatti che se un prodotto viene considerato come termine di paragone per un settore vuol

dire che dal punto di vista del mercato si è dimostrato un successo.

L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo

business. I suoi punti di forza sono quindi la facilità d'uso, l'estetica e l'usabilità nella

navigazione in internet, oltre ad avere una suite completa di programmi per l'ufficio.

L'innovazione che ha portato nel settore è sicuramente nelle sue caratteristiche hardware1,

ma sopratutto nell'usabilità, superiore a tutti i suoi predecessori. In sostanza è la sintesi di

un dispositivo hardware di elevato design, supportato da un sistema operativo semplificato

che deriva da Mac OS X, il sistema Apple per computer Desktop. iPhone OS infatti deriva

da Darwin, il kernel di Mac OS X. La struttura software inoltre ricalca abbastanza

fedelmente la struttura che è possibile trovare sui desktop di casa Apple. Le differenze tra i

due sistemi quindi, riguardano quasi esclusivamente l'interfaccia grafica e gli strumenti di

interazione con l'utente.

Il contributo che lo studio di questa tesi vuole offrire, è lo studio della piattaforma

software implementata sull'iPhone. È interessante infatti osservare il sistema operativo 1 L'iPhone è un dispositivo senza tasti reali se non uno che porta al menu generale. Tutte le sue funzioni sono quindi

accessibili tramite tecnologia multi-touch.

Page 10: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

10

implementato ed i framework supportati che permettono lo sviluppo di applicazioni

perfettamente coerenti con gli standard Apple e con l'usabilità che contraddistingue i suoi

software. Il sistema operativo iPhone OS è presente sia nel dispositivo mobile iPhone ma

anche nel lettore multimediale iPod Touch. Tale supporto infatti permette l'utilizzo delle

stesse applicazioni software, le limitazioni a cui va incontro riguardano esclusivamente

l'hardware. Ulteriore approfondimento offerto dallo studio che segue riguarda il

linguaggio ad oggetti Objective-C e gli strumenti di sviluppo distribuiti dalla Apple. Tale

linguaggio è infatti il privilegiato per lo sviluppo di applicazioni per sistemi Mac OS X ed

iPhone OS. Objective-C nasce dall'esigenza di estendere alla programmazione ad oggetti il

linguaggio C, è stato quindi descritto nelle sue caratteristiche principali. Objective-C nella

sua struttura è meno tipizzato di C++ ed è basato essenzialmente sullo scambio di

messaggi e su di una estrema dinamicità. In fase di esecuzione infatti Objective-C fornisce

un maggior supporto run-time alla riflessione rispetto a C++. Questa caratteristica rende

infatti Objective-C più orientato verso decisioni “dinamiche” del C++.

Il percorso seguito nello studio affrontato quindi parte dalle principali offerte commerciali

del settore e termina con lo sviluppo di una applicazione come caso di studio.

Il primo capitolo quindi riguarda il confronto delle principali offerte commerciali di

piattaforme software, proposte dalle diverse case produttrici. È interessante infatti

osservare come le diverse offerte si differenzino per il tipo di licenza d'uso utilizzata per il

sistema operativo offerto. Inoltre sono presenti differenze anche riguardo alle possibilità

che vengono date a sviluppatori di terze parti di produrre software dedicato. Tali approcci

infatti permettono di differenziare anche il target di riferimento tra gli utenti. Dare inoltre

la possibilità a sviluppatori e società esterne di creare software dedicato, apre nuovi

mercati e nuove potenzialità per il settore nonché per la piattaforma che offre tale

possibilità.

Il secondo capitolo invece si occupa nello specifico di studiare il sistema operatvo iPhone

OS. Tale studio quindi permette di relazionare il sistema implementato sul dispositivo

Page 11: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

11

mobile con quello offerto sulle piattaforme desktop. Apple, come si è anticipato, non ha

infatti implementato un sistema operativo finalizzato alle dispositivi mobili, ma ha

adattato un sistema maturo come Mac OS X 10.5.

Si è affrontato nel terzo capitolo invece lo studio dei framework implementati sul

dispositivo. Attraverso tali framework è infatti possibile accedere a tutte le sue

funzionalità hardware. Apple inoltre offre agli sviluppatori strumenti che facilitano la

costruzione di software, delle sue interfacce grafiche e di strumenti che ottimizzano le

prestazioni del codice sviluppato. Insieme ai framework quindi ci si è soffermati sugli

strumenti di sviluppo, che permettono di costruire applicazioni coerenti a tutti i software

per iPhone. La coerenza ti tali strumenti permette agli utenti di avere familiarità con ogni

applicazione utilizzata. Anche in questo capitolo si è affrontato lo studio confrontando i

framework implementati in iPhone OS con quelli per Mac OS X.

Nel quarto capitolo ci si è dedicati allo studio di Objective-C. Tale linguaggio è infatti

consigliato e supportato dalla Apple per lo sviluppo di software per Mac OS X ed iPhone

OS. Objective-C è un linguaggio orientato agli oggetti. La sua principale differenza con il

C++ è il maggior supporto runtime alla riflessione. In Objective-C si può interrogare un

oggetto riguardo alle sue stesse proprietà, ad esempio se possa o meno rispondere ad un

dato messaggio, mentre in C++ ciò è impossibile a meno di fare ricorso a librerie esterne.

Nel capitolo finale si è costruito un software come caso di studio per affrontare alcune

delle tematiche descritte nei capitoli precedenti. In sostanza si sono utilizzati gli strumenti

di sviluppo forniti alla Apple, il linguaggio di programmazione ed alcune caratteristiche

hardware e software del dispositivo.

È possibile quindi, attraverso i cinque capitoli dello studio affrontato, ricostruire un quadro

completo del dispositivo mobile prodotto da Apple.

Page 12: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

12

Capitolo 1 Sistemi operativi per dispositivi mobili

Negli ultimi anni il mercato ha visto la diffusione di dispositivi mobili dotati di sistemi

operativi in grado di offrire servizi e funzionalità sempre più complesse. Inoltre la

diffusione dell'utilizzo di servizi internet, ha reso necessario fornire un semplice cellulare

o dispositivi più complessi della possibilità di navigare nel web. La ricerca quindi di

maggiore efficienza e funzionalità, ha spinto alcuni produttori a fornire tali dispositivi di

sistemi operativi offerti già in ambiente Desktop, oppure sviluppare soluzioni

appositamente progettate.

Un ambiente per dispositivi mobili, per sua natura, deve offrire anche funzionalità diverse

da un ambiente desktop, senza trascurare le limitazioni hardware che necessariamente

dovrà affrontare. Bisogna infatti valutare i limiti che riguardano ad esempio il display di

ridotte dimensioni, un processore di ridotte capacità elaborative, senza sottovalutare la

necessità di garantire al dispositivo una discreta autonomia elettrica. Inoltre bisogna

considerare che i sistemi operativi per dispositivi mobili potrebbero non supportare

hardware dedicato al trasferimento di dati (DMA) o per la protezione della memoria

(MMU). Un sistema desktop inoltre usufruisce di memoria virtuale che in un dispositivo

mobile risulta estremamente ridotta. Bisogna inoltre fare scelte semplificative, in quanto

un dispositivo mobile potrebbe non supportare algoritmi complessi per lo scheduling di

processi e thread implementati dai sistemi desktop. Altra difficoltà a cui vanno incontro

tali soluzioni riguardano la gestione di una possibile tastiera, fornendo eventualmente

strumenti alternativi di input con i quali interagire con l'utente.

Esistono quindi diverse soluzioni che vengono incontro a tali necessità, affrontate con

altrettanti approcci commerciali. Tra le diverse soluzioni che sintetizzeremo in questo

capitolo si potranno osservare le differenze commerciali che riguardano sia l'accesso al

codice sorgente del sistema operativo, che la possibilità di sviluppare applicazioni di terze

parti da poter istallare.

Page 13: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

13

Di seguito osserveremo sinteticamente le piattaforma per dispositivi mobili che si sono

distinte nel panorama commerciale, valuteremo quindi Symbian, Windows Mobile,

Android ed iPhone.

1.1. Sistema Operativo Symbian

Anche se la nascita di Symbian (Ascione, 2005) risale al 1998, bisogna considerare che il

progetto risale a molti anni prima, la prima versione infatti è datata 1989 con il nome

EPOC2. La PSION3, società entrata nella storia per aver prodotto il primo modello di

PDA4, sviluppò questo sistema operativo dalle caratteristiche innovative per quegli anni.

Era completamente multi-tasking, offriva un’interfaccia grafica ed era un’assoluta novità

se si considera che la Microsoft non aveva ancora messo in esercizio il sistema operativo

Windows.

Nel 1998 la PSION Software realizzò una fusione con Nokia, Motorola ed Ericsson per

creare Symbian con l’obiettivo di costruire un sistema operativo che potesse adattarsi a

qualunque dispositivo, dai telefoni cellulari ai palmari.

Ben presto anche altri produttori si resero conto dell’importanza del progetto e vollero

prendervi parte. L’anno seguente (1999) Matsushita, anche nota come Panasonic, acquistò

quote della società appena formata. L’ambiziosità del progetto valse a Symbian il

riconoscimento di ‘Miglior compagnia’ con il progetto a maggior potenziale nel lungo

termine.

Nel 2000 ci fu il debutto del primo modello di cellulare dotato di sistema operativo

Symbian; l’R380 prodotto dalla Ericsson. Adottava la versione 5.0 di Symbian che era

direttamente derivata da EPOC. L’anno successivo fu rilasciata la versione 6.0 che fu

installata da Nokia su tutta la serie dei Communicators 9210. Intanto il numero di società

2 EPOC deriva da Epoch ed indica la nascita di una nuova era nel campo informatico, quella dei computer tascabili. 3 PSION è l’acronimo di Potter’s Software Instrument, ossia strumentazioni scientifiche di David Potter, il fondatore

della società, a cui fu aggiunto “ON”. 4 Personal Digital Assistant

Page 14: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

14

coinvolte nel progetto Symbian cresceva grazie alla partecipazione di Sony, Sanio e

Fujitsu.

Nel 2002 fu annunciata la nascita della versione 7.0 di Symbian. Il primo telefono

cellulare ad adottare tale versione fu il Nokia 6600, che nel 2003 invase i mercati.

La storia degli ultimi anni ha visto Symbian affermarsi leader nel campo dei sistemi

operativi per dispositivi mobili, la versione attualmente diffusa è la versione 9.5

annunciata nel marzo 2007.

Gli sviluppatori modificano costantemente questa struttura per integrare nuovi protocolli e

funzionalità in modo da rispondere alle esigenze delle società facenti parte del consorzio.

Come altri sistemi operativi, Symbian dispone di funzionalità di multithreading,

multitasking e protezione della memoria. Grande importanza è data all'utilizzo della

memoria mediante tecniche specifiche di Symbian che determinano la rarità degli errori

dovuti a una cattiva gestione della memoria (memory leak). Tecniche analoghe permettono

un'altrettanto efficiente gestione dello spazio su disco. Il funzionamento di Symbian è

basato su eventi e la CPU è automaticamente disabilitata quando non vi siano eventi attivi:

il corretto uso di questa tecnica aiuta ad assicurare alle batterie una durata maggiore,

caratteristica molto importante sui dispositivi mobili.

Nonostante l'origine di Symbian veda un consorzio di più società come trampolino di

lancio, bisogna notare che nel giugno del 2008 Nokia ha comunicato l'intenzione di

rilevare le quote azionarie delle altre società, al fine di divenire l'unico proprietario del

sistema operativo. Una volta completata l'acquisizione, Nokia ha comunicato l'intenzione

di renderlo open source, con la creazione di Symbian foundation. Tale fondazione, formata

dai vecchi proprietari e aperta ad altri produttori, si dovrà occupare di unificare tutte le

interfacce in una nuova release del sistema e gestirne l'apertura agli sviluppatori esterni.

Symbian non è difatti attualmente un sistema operativo open source, poiché il codice

sorgente non è disponibile pubblicamente; tuttavia, quasi tutto il codice è fornito ai

produttori di dispositivi mobili basati su Symbian e ad altri operatori. Inoltre, anche la

Page 15: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

15

documentazione relativa alle API è disponibile pubblicamente, quindi chiunque ha la

possibilità di sviluppare software per Symbian.

In sostanza è possibile considerare il nuovo approccio di Nokia come la risposta

commerciale al progetto open source Android di Google, rigenerando un prodotto che

detiene già una grossa fetta di mercato delle piattaforme per dispositivi mobili. Il nuovo

progetto di Nokia infatti, si pone in una strategia di mercato non completamente open

source come Android, ma neanche completamente proprietaria come Windows Mobile di

Microsoft o iPhone OS di Apple. È infatti importante sottolineare che se è possibile

sviluppare applicazioni per Symbian, esistono solo due percorsi per installarle sui

dispositivi, attraverso pacchetti SYS oppure attraverso la preistallazione sui dispositivi da

parte di case produttrici di cellulari. Dalla versione 9.x però è stato introdotto un vincolo

per i pacchetti SYS, in quanto l'applicazione per essere installata deve essere “firmata”

(Symbian Signed) da Symbian. Con l'introduzione di tale sistema gli sviluppatori devono

pagare per utilizzare alcune delle caratteristiche più interessanti dei dispositivi mobili. Tale

vincolo ha reso Symbian meno popolare nella comunità Open Source.

Il linguaggio nativo di Symbian è il C++. Ci sono molteplici piattaforme basate su

symbian OS che forniscono SDK per sviluppatori. Singoli produttori di cellulari spesso

hanno SDK o loro estensioni direttamente scaricabili dai propri siti. Gli SDK in genere

contengono documentazione, header file e librerie necessarie per produrre software per

Symbian OS. Con la versione 9 del sistema operativo è stato aggiornato il compilatore che

include una nuova versione di GCC. Bisogna notare però che la curva di apprendimento

per sviluppare software è molto ripida. È infatti molto complicato sviluppare anche

programmi semplici e questo è dovuto al fatto che i paradigmi di programmazione sono

legati ancora a standard dei dispositivi degli anni 90. Nonostante il linguaggio nativo sia il

C è possibile sviluppare anche in OPL, Python, Visual Basic, Simkin e Perl, oltre a Java

ME e PersonalJava.

Page 16: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

16

1.2. Sistema Operativo Windows Mobile

Windows Mobile di Microsoft è un sistema operativo compatto, basato sulle API Win32.

In perfetto stile Microsoft tale sistema operativo è stato prodotto per diverse piattaforme

hardware, in modo da essere supportato da più dispositivi mobili, fra questi possiamo

elencare i Pocket PC, gli Smartphone ed i Portabile Media. Windows Mobile è nato nel

2003, attualmente è stata rilasciata la versione 6.1 e per il 2009 è prevista la versione 7.

La scelta commerciale di Microsoft ha privilegiato la migrazione del sistema operativo per

desktop su di un ambiente mobile. La scelta commerciale quindi ha visto prevalere la

volontà di aprire un nuovo mercato per un sistema operativo esistente e diffuso: Windows.

Un utente medio quindi utilizza sul dispositivo mobile un ambiente che generalmente

utilizza sul proprio desktop. Microsoft quindi ha scelto di alleggerire il sistema operativo

Windows delle caratteristiche più avide di risorse, senza ricorrere allo sviluppo di una

piattaforma dedicata. Nelle sue scelte commerciali inoltre ha ritenuto di lasciare il codice

del Sistema Operativo protetto da Copyright, ma permettendo a sviluppatori di terze parti

di creare software dedicato.

Il framework messo a disposizione degli sviluppatori è il Microsoft .NET Compact

Framework (.NET CF), una versione di .NET Framework ottimizzata per Windows CE.

Tale framework è una versione semplificata del più noto .NET Framework, in più dispone

di librerie costruite specificatamente per dispositivi mobili.

La versione di Windows sulla quale si basa Windows Mobile è Windows CE (Compact

Edition). Windows CE è derivato dalla famiglia Windows, ma ha un kernel differente e

non è quindi una semplice "riduzione". Le API e l'aspetto grafico sono comunque molto

simili.

Essendo Windows CE sufficientemente modulare e flessibile sono state quindi sviluppate

versioni differenti5. Tali specifiche versioni prendono il nome "commerciale" di MS

5 Bisogna considerare inoltre le differenti piattaforma hardware. Bisogna considerare infatti i processori differenti dal

x86, come MIPS, ARM e Hitach SuperH.

Page 17: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

17

Handheld 3.0 (e 3.1), MS Handheld 2000, Microsoft Pocket PC 2000 (e 2002), MS

Smartphone 2002, MS Windows Mobile 2003 (e 2003 Second Edition), MS Windows

Mobile 5.0 e successive. Tali varianti fanno tutte riferimento a specifiche evoluzioni della

piattaforma Windows CE, passato dalla v1.0 alla v6.1. Windows CE è un sistema

operativo ottimizzato per dispositivi con risorse limitate, ciò vuol dire ad esempio che il

suo kernel necessita, per l'avvio, di meno di un mega byte di memoria. Spesso inoltre è

configurato su dispositivi senza dischi di memoria.

1.3. Sistema Operativo Android

Nel luglio 2005 Google acquisì Android (Alfieri, 2006), una piccola compagnia di

sviluppo software con sede a Palo Alto, ed incluse in Google tutti i soci fondatori. In quel

periodo Android era ancora sconosciuta e si vociferava che Google volesse entrare nel

mercato dei dispositivi mobili. Da allora in più di un'occasione Google ha dimostrato di

essere interessata al settore, convergendo la sua ricerca verso un sistema basato su linux,

flessibile e utilizzabile su più dispositivi hardware. Nel Novembre 2007 si costituisce così

l'Open Handset Alliance (OHA). Tale Accordo commerciale include 34 compagnie con

Google come capofila, tra produttori di dispositivi mobili, società di software e soggetti

del settore delle telecomunicazioni, il cui obiettivo è sviluppare "standard aperti" per

dispositivi mobili. Android quindi è una piattaforma open source per telefoni cellulari,

basata sul sistema operativo Linux e sviluppata dall'Open Handset Alliance (OHA). Tale

proposta commerciale quindi si pone in competizione con altri soggetti del mercato, con

una strategia commerciale assolutamente differente. Nonostante ci siano stati altri casi di

sviluppo di sistemi open source per cellulari, come OpenMoko, Android è il primo caso

che vede investimenti ingenti da parte di colossi del mercato delle telecomunicazioni.

Al fine di favorire lo sviluppo di applicazioni per la piattaforma, nel gennaio 2008, Google

ha indetto un concorso a premi legato allo sviluppo di applicazioni per Android. Dal

concorso risultarono esclusi i programmatori residenti a Cuba, Iran, Siria, Nord Corea,

Page 18: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

18

Sudan, Burma (Myanmar), Quebec e Italia. Le nazioni sono state escluse per adempire alla

legislazione statunitense contro il terrorismo o per impedimenti burocratici locali come nel

caso dell'Italia.

Bisogna segnalare inoltre che nell'agosto 2008 è stato presentato il primo esemplare di

dispositivo mobile con Android installato, prodotto da T-Mobile, HTC e Google. Il 22

Ottobre verrà venduto negli USA con un vincolo di contratto con T-mobile.

La piattaforma Android quindi è uno stack software per dispositivi mobili che include al

suo interno un Sistema Operativo, un Middelware ed alcune applicazioni chiave. Gli

sviluppatori possono creare applicazioni per la piattaforma usando l'apposito SDK messo a

disposizione per Android. Tali applicazioni dovranno essere scritte utilizzando il

linguaggio java e dovranno girare su Dalvik, una Virtual Machine progettata per

dispositivi mobili e che necessita a sua volta di un kernel linux.

Il 12 novembre 2007, l'OHA infatti ha rilasciato il software development kit (SDK) che

include: strumenti di sviluppo, librerie, un emulatore del dispositivo, la documentazione

(in inglese), alcuni progetti di esempio, tutorial, FAQ, e altro. Tale software di sviluppo è

installabile su qualsiasi computer x86 che usa come sistema operativo Windows XP o

Vista, Mac OS X 10.4.8 e successivi, o Linux. È anche possibile utilizzare il plug-in per

Eclipse. L'SDK è stato aggiornato alla versione 0.9 il 18 agosto 2008, questa nuova

versione è ormai la definitiva, saranno infatti minime le modifiche effettuate con il rilascio

della versione 1.0, di cui saranno dotati i primi device.

Android contiene al suo interno un insieme di applicazioni principali che ne costituiranno

il core: un client di posta e-mail, un programma per gli sms, un gestore del calendario, un

programma per la consultazione di mappe e cartine, un browser, un'agenda per i contatti e

così via. Tali applicazioni sono sviluppate in linguaggio Java.

Gli sviluppatori avranno pieno accesso allo stesso Framework ed alle stesse API utilizzate

dalle applicazioni del Core. L'architettura delle applicazioni è pensata per semplificare al

massimo il riuso dei componenti: ogni applicazione potrà rendere note le sue potenzialità e

Page 19: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

19

le altre applicazioni potranno fare uso delle stesse (a patto di rispettare i vincoli sulla

sicurezza imposti dal framework). Tale meccanismo offre un modo estremamente

semplice per sostituire o aggiornare componenti da parte dell'utente.

Per sviluppare le applicazioni esistono un vasto insieme di servizi e sistemi tra i quali una

ricca gamma di controlli, un provider dei contenuti che rende le applicazioni capaci di

accedere contenuti di altre applicazioni, un gestore delle risorse, un gestore delle notifiche

ed un gestore delle attività. Tali strumenti permettono così di sviluppare agevolmente

anche applicazioni complesse ed allo stesso tempo permetterà un facile aggiornamento

delle stesse con la sostituzione di singoli componenti elementari. Android include anche

un vasto insieme di librerie scritte in C/C++ utilizzate da vari componenti del sistema

stesso. Queste potenzialità sono disponibili agli sviluppatori attraverso il Framework

applicativo di Android. Tra le principali librerie troviamo anche Librerie di sistemi C

ottimizzate per dispositivi mobili basati su linux, Librerie multimediali, un gestore delle

interfacce, una libreria WebCore, SGL (per lo sviluppo 2D), librerie 3D ed SQLite, come

Data Base da utilizzare alla base delle applicazioni. Android include anche un set di

librerie del Core che forniscono la maggior parte delle funzionalità disponibili nelle

librerie di sistema del linguaggio di programmazione Java standard. Tutti i software

sviluppati, a differenza di altre piattaforme, non sono comunque posti a nessun vincolo per

la loro installazione.

È da notare comunque il carattere innovativo di tale progetto in quanto dal 21 ottobre 2008

la piattaforma è reperibile come Android Open Source Project. Bisogna comunque notare

che alcune parti di Android che si riferiscono a specifico hardware non sono rilasciate

come open source e non vengono, comunque, considerate parte integrante del progetto.

Altre limitazioni alla licenza fanno emergere dubbi su quanto Google voglia gestire in stile

open source tale piattaforma, inoltre c'è da dire che attraverso la licenza Apache è data la

possibilità a produttori di terze parti di sviluppare estensioni software senza dover

sottoscrivere una licenza open source. Tale approccio, secondo molti esperti del settore,

Page 20: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

20

genererà un proliferare di licenze alternative. Google comunque ha dichiarato in più di

un'occasione a voler mantenere il progetto Open Source.

Si devono comunque segnalare altri progetti che vedono linux come sistema operativo per

dispositivi mobili. Uno di questi è Maemo, basato sulla distribuzione linux Debian. Tale

sistema è utilizzato da Nokia per alcuni dispositivi portatili touch screen.

1.4. Sistema operativo iPhone OS

Apple inc. ha fatto il suo ingresso nei dispositivi mobili nel 2007 con una prima versione

dell'iPhone, successivamente nel luglio del 2008 è stata presentata una seconda versione

disponibile in molti più Paesi.

Come tutti gli altri prodotti Apple, anche con l'iPhone, la casa produttrice ha deciso di

legare il sistema operativo ad un unico dispositivo hardware. A differenza quindi dei suoi

concorrenti non ha previsto la portabilità del suo sistema su altri dispositivi. Il sistema

operativo in oggetto è inoltre l'apertura nel settore mobile del sistema operativo già

utilizzato in ambiente desktop.

La descrizione dettagliata di tale sistema verrà offerta nei capitoli successivi. L'unica

caratteristica degna di nota in questo frangente è il ritorno ad un ambiente chiuso di

sviluppo del sistema operativo in cui la casa produttrice detiene tutti i diritti. Inoltre Apple

ha rilasciato un kit di sviluppo per applicazioni di terze parti, ma prima di essere installate

sui dispositivi necessitano di un'approvazione della Apple stessa. È possibile quindi

sintetizzare l'approccio commerciale di Apple come in antitesi con il diretto concorrente

Android.

Page 21: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

21

Capitolo 2 Struttura del sistema operativo iPhone OS

2.1. Stratificazione

iPhone OS (Apple, The Cocoa Environment) è costituito da 4 strati. Cocoa Touch, Media,

Core Services e Core OS (Figura 1). Gli strati più bassi del sistema sono i servizi

fondamentali su cui si basano tutte le applicazioni, mentre gli strati di livello superiore

contengono tecnologie e servizi più sofisticati.

Gli strati più alti forniscono astrazioni dei costrutti dei livelli inferiori, facilitando lo

sviluppo di software. L'accesso ai livelli più bassi è comunque garantito agli sviluppatori

che ne vogliano sfruttare tutte le potenzialità.

2.2 Cocoa Touch

Lo strato Cocoa Touch comprende i framework UIKit e foundation (UIKit.framework e

Foundation.framework), che forniscono gli strumenti di base e le infrastrutture necessarie

per realizzare la grafica e le applicazioni in iPhone OS. Cocoa Touch comprende anche

altri servizi chiave per accedere alle caratteristiche del dispositivo, ad esempio i contatti

dell'utente.

UIKit (UIKit.framework) è un framework Objective-C (Apple, The Objective-C 2.0

Programming Language, 2006) necessario per la realizzazione delle infrastrutture grafiche

Figura 1: Stratificazione iPhone OS

Page 22: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

22

nelle applicazioni in iPhone OS.

Ogni applicazione utilizza Cocoa Touch per l'implementazione delle seguenti

caratteristiche:

• Application Management

• Supporto alla Grafica

• Supporto alla gestione di eventi

• Gestione dell'interfaccia utente

• Oggetti che rappresentano le interfacce ed i controlli standard del sistema

• Supporto per testo e contenuti web

o Oltre a fornire il codice fondamentale per costruire le applicazioni, UIKit incorpora

anche il supporto per alcune funzioni specifiche del dispositivo come quelle elencate

di seguito:

• Accelerometro dati

• La fotocamera integrata

• La libreria fotografica dell'utente

• Device-specific information

2.3 Media

Lo strato Media provvede a fornire strumenti per la gestione della grafica, dell'audio e

delle tecnologie interne, volti a velocizzare lo sviluppo di applicazioni che sfruttano le

caratteristiche hardware del dispositivo. I framework degli strati alti rendono facile la

creazione di animazioni grafiche ed i livelli inferiori del framework danno accesso agli

strumenti necessari per personalizzare al meglio il software da implementare.

Di seguito verranno descritte le tecnologie incluse nello strato Media, che a loro volta

includono set di librerie.

2.3.1 Tecnologie Grafiche

La grafica è una caratteristica importante per tutte le applicazioni iPhone. Ogni qualvolta

Page 23: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

23

sia possibile, lo sviluppatore può sfruttare immagini, View e funzioni fornite dal

framework UIKit per migliorare l'interfaccia utente dell'applicazione sviluppata. Se tali

strumenti forniti da UIKit dovessero risultare insufficienti è sempre possibile accedere alle

tecnologie descritte di seguito. Le seguenti librerie infatti sono strumenti molto utili per

gestire ogni aspetto grafico 2D e 3D delle applicazioni.

OpenGLES.framework

Il framework OpenGL ES si basa sulle specifiche OpenGL ES v1.1 e fornisce strumenti

per il disegno di contenuti 2D e 3D. È un framework scritto in C che lavora a stretto

contatto con l'hardware per fornire un elevato frame rate, fondamentale nello sviluppo di

giochi.

OpenGLES.framework è sempre usato in congiunzione con le interfacce EAGL. Tali

interfacce sono parte del framework OpenGL ES e fanno da interfaccia tra il codice dei

disegni OpenGL ES e le finestre dell'applicazione da sviluppare.

QuartzCore.framework

Il framework Quartz Core contiene le interfacce Core Animation. Core Animation è

un'avanzata tecnologia di animazione che utilizza un path di rendering ottimizzato per

attuare complesse animazioni ed effetti visivi.

Fornisce un' interfaccia di alto livello objective-C per la configurazioni di animazioni ed

effetti. Successivamente il rendering è realizzato in hardware per migliorare le prestazioni.

Core Animation è integrato in più parti del Sistema Operativo iPhone OS includendo

alcune classi UIKit come UIView e fornendo animazioni per diversi effetti grafici classici

del sistema operativo. E' possibile utilizzare interfacce Objective-C di questo framework

per creare animazioni personalizzate.

CoreGraphics.framework

Il Framework Core Graphics (CoreGraphics.framework) contiene le interfacce per il

disegno Quartz 2D. Quartz è lo stesso framework utilizzato per il disegno in Mac OS X.

Fornisce il supporto per il disegno base, antialiasing, rendering, gradienti, immagini,

Page 24: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

24

colori, trasformazioni spaziali, creazione di pdf, visualizzazione ed analisi. Anche se l'API

è basato su C, utilizza oggetti basati su astrazioni per rappresentare gli oggetti

fondamentali dei disegni, semplificando il riutilizzo dei contenuti grafici.

2.3.2 Tecnologie Audio

Le tecnologie audio offerte in iPhone OS includono la capacità di riprodurre e registrare

audio di alta qualità nonché di gestire le funzionalità di vibrazione del dispositivo. Le

tecnologie audio supportano i seguenti formati:

• AAC

• Apple Lossless (ALAC)

• A-law

• IMA/ADPCM (IMA4)

• Linear PCM

• µ-law

Core Audio

Core Audio è un'interfaccia di base che supporta la manipolazione di audio multicanale, è

possibile quindi generare, registrare, mescolare e riprodurre audio. È inoltre possibile

utilizzare Core Audio per accedere alle funzionalità di vibrazione.

Sono previsti i seguenti framework:

CoreAudio.framework

Fornisce informazioni sulle caratteristiche audio e sul formato di file.

AudioToolbox.framework

Fornisce servizi di riproduzione e registrazione per file e flussi audio. Questo framework

prevede anche il supporto per la gestione di file audio e riproduzione di suoni ed allarmi di

sistema.

AudioUnit.framework

Fornisce servizi per l'utilizzo di unità audio e moduli di elaborazione.

Page 25: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

25

OpenAL

Oltre a Core Audio, iPhone OS include il supporto per l'audio Open Library (OpenAL).

L'interfaccia OpenAL è uno standard multipiattaforma per la gestione 3D audio nelle

applicazioni. È possibile quindi utilizzare questa libreria in tutte le applicazioni che, come

i giochi, richiedono caratteristiche audio di alta qualità e di gestione 3D dello stesso.

2.3.3 Tecnologie Video

iPhone OS fornisce supporto per i video full screen attraverso il framework Media Player

(MediaPlayer.framework). Questo framework supporta la riproduzione di file video con

estensione .mov .mp4 .m4v .3gp ed usa le compressioni standard H.264, MPEG-4 Part 2

video e numerosi formati audio, tra cui: AAC, Apple Lossless (ALAC), µ-law, linear

PCM, IMA/ADPCM (IMA4), A-law.

2.4 Core Services

Il Core services fornisce i servizi di sistema necessari a tutte le applicazioni. Anche non

utilizzando tale strato in maniera diretta, ogni altra tecnologia nel sistema si basa su di

esso.

Core Services quindi fornisce i seguenti servizi:

• Address Book

• Core Foundation

• Core Location

• CFNetwork

• Security

• SQLite

• XML Support

2.4.1 Address Book

Il framework Address Book (AddressBook.framework) fornisce un accesso ai contatti

salvati sul dispositivo. Le applicazioni che hanno bisogno di queste informazioni, come

Page 26: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

26

programmi di mail o di chat, possono usare questo framework per accedere direttamente ai

dati dei contatti salvati, tali programmi possono usare i dati sia internamente che

visualizzarli in un'interfaccia grafica.

Il framework Address Book UI (AddressBookUI.framework) completa

AddressBook.framework fornendo un'interfaccia grafica per accedere ai contatti utente,

utilizzando classi Objective-C di questo framework è possibile usare le interfacce standard

del sistema per presentare i contatti e crearne di nuovi.

2.4.2 Core Foundation

Il framework Core Foundation (CoreFoundation.framework) è un set di interfacce che

forniscono gestione dei dati di base e dei servizi per le applicazioni in iPhone.

Questo framework fornisce supporto per:

• Tipi di dato Collection (arrays, sets, e così via)

• Bundle

• Gestione di stringhe

• Gestione delle date e del tempo

• Gestione di blocchi di dati grezzi

• Gestione delle preferenze

• Manipolazione di stream e di URL

• Supporto a Thread ed all'avvio del Loop

• Comunicazione di porte e Socket

Il framework Core Foundation è strettamente collegato al framework Foundation, che

fornisce interfacce Objective-C per le stesse caratteristiche di base. In situazioni dove si

necessita mischiare oggetti Foundation e tipi Core Foundation è possibile utilizzare un

ponte “toll-free” che esiste tra i due framework. Per “toll-free” si intende la possibilità di

usare tipi Core Foundation e Foundation in maniera intercambiabile nei metodi e nelle

funzioni dei rispettivi framework. Questa caratteristica è abilitata per molti tipi di dati,

Page 27: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

27

incluse collection e tipi di dato stringa. La descrizione di tipi e classi per ogni framework,

indica se un oggetto è toll-free e, nel caso, il tipo di oggetto e con chi è collegato.

2.4.3 Core Location

Il framework Core Location (CoreLocation.framework), permette di stabilire la corretta

latitudine e longitudine del dispositivo, il framework infatti utilizza le caratteristiche

hardware per determinare la posizione geografica del dispositivo, attraverso il GPS, la

triangolazione delle celle o le informazioni del segnale WiFi. La precisione con cui

elabora la locazione è in funzione della tecnologia che utlizza per ricavarla. L'applicazione

Maps utilizza questa caratteristica per visualizzare in una mappa la posizione corrente

dell'utente, è così possibile integrare questa tecnologia in qualunque applicazione necessita

di informazioni sulla posizione geografica. Un esempio possibile è l'individuazione di

servizi, locali o ristoranti nelle vicinanze della posizione localizzata.

2.4.4 CFNetwork

Il framework CFNetwork (CFNetwork.framework) è un set di interfacce che fornisce

astrazioni orientate ad oggetti per gestire i protocolli di networking. Tali astrazioni

forniscono controllo dettagliato sul protocollo dello stack e facilitano l'utilizzo di costrutti

di basso livello come i socket BSD. Inoltre questo framework facilita compiti come la

comunicazione via FTP e server HTTP e risolve host DNS.

Di seguito sono elencati alcuni compiti facilitati dal framework CFNetwork:

• Uso di Socket BSD

• Creare connessioni protette SSL o TLS

• DNS hosts

• Lavorare con server HTTP e HTTPS

• Lavorare con server FTP

• Pubblicare, risolvere, e cercare servizi Bonjour

Page 28: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

28

2.4.5 Security

In aggiunta alle caratteristiche integrate di sicurezza, iPhone OS fornisce un framework

(Security.framework) esplicitamente dedicato agli sviluppatori che vogliano aumentare la

sicurezza nella gestione dei dati nelle applicazioni. Tale framework fornisce interfacce per

gestire certificati, a chiave pubblica e privata e politiche di sicurezza, supporta infatti la

generazione pseudo casuale di numeri crittograficamente sicuri. Inoltre fornisce supporto

al salvataggio di certificati e chiavi crittografate nel portachiavi (keychen), un luogo sicuro

per salvare dati sensibili degli utenti.

Le interfacce CommonCrypto forniscono supporto addizionale per codifica simmetrica,

HMAC e Digests. Le caratteristiche Digests supportano funzioni compatibili con le

funzionalità normalmente trovate nelle librerie OpenSSL, non disponibili in iPhone OS.

2.4.6 SQLite

La libreria SQLite fornisce la possibilità di integrare nell'applicazione un piccolo database

SQL, senza dover accedere in remoto ad un altro database. Nell'applicazione quindi è

possibile creare un file database locale e gestire tabelle e record direttamente su questo

file. La libreria è costruita per un uso generico, ma è ottimizzato per fornire un accesso più

rapido ai record del database.

2.4.7 XML Support

Il framework Foundation fornisce la classe NSXMLParser per recuperare elementi da un

documento XML. In aggiunta, il supporto alla manipolazione di contenuti XML è fornito

dalla libreria libXML2. Questa libreria open source permette di analizzare o scrivere dati

XML in modo rapido e trasformare facilmente il contenuto XML in HTML.

2.5 Core OS

iPhone OS, nel suo strato Core OS, fornisce un insieme di interfacce per l'accesso a molte

funzionalità di basso livello del sistema operativo. La richiesta di accessi a queste

funzionalità avviene attraverso la libreria LibSystem. Le interfacce forniscono il supporto

Page 29: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

29

alle seguenti funzionalità:

• Threading (POSIX threads)

• Networking (BSD sockets)

• Accesso al File-system

• Standard I/O

• Bonjour e servizi DNS

• Locale information

• Allocazione della Memoria

• Math computations

Lo strato Core OS comprende il kernel, driver e l'interfaccia di base del sistema operativo.

La struttura del kernel è ereditata da Mac OS X che a sua volta è basato sul progetto

Darwin, in particolare la versione iPhone OS 1.0 è basata su Darwin 9.0.0d1.

Specificatamente per iPhone ed iPod touch il sistema operativo è stato ottimizzato per

CPU con architettura ARM.

2.5.1 XNU

Darwin è costruito su XNU, un kernel che può essere visto in maniera semplificata come

composto da un core basato su Mach (Cesare, 2007) 3, una “personalità” da sistema

operativo basata su FreeBSD 5 ed un ambiente runtime orientato agli oggetti per le

estensioni del kernel (driver compressi).

È da notate che un kernel in esecuzione contiene numerosi driver che non risiedono nel

codice base del kernel, ma hanno i propri package Darwin. Da questo punto di vista è

possibile affermare che il kernel di Mac OS X è qualcosa di più di XNU anche se al

termine XNU si fa riferimento al codice di base più tutte le estensioni del kernel stesso.

Fatta questa premessa possiamo considerare le seguenti parti principali del kernel di Mac

OS X:

• Mach – lo strato di servizio

Page 30: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

30

• BSD (Cesare, 2007) – il fornitore primario dell'interfaccia di programmazione di

sistema

• L'I/O Kit (Cesare, 2007) – l'ambiente di runtime per i driver

2.5.1.1 Mach

Se il kernel XNU è il cuore del Mac OS X, allora il Mach può essere considerato il cuore

di XNU. Il Mach fornisce servizi di basso livello critici che sono trasparenti alle

applicazioni. Gli aspetti del sistema di cui è responsabile il Mach includono:

• Astrazione hardware (in parte)

• Gestione del processore (incluso lo scheduling ed il multiprocessing simmetrico)

• Preempitive multitasking (incluso i supporto ai task ed ai thread)

• Gestione della memoria virtuale (incluso il paging di basso livello, la protezione della

memoria, la condivisione e l'ereditarietà)

• Meccanismi IPC di basso livello (che sono la base dello scambio di messaggi nel

kernel)

• Supporto real-time (che permette alle applicazioni time-sensitive di avere accesso

latency-bounded alle risorse del processore)

• Supporto al debugging del kernel6

• Console I/O

Mach inoltre gestisce nativamente la presenza di più architetture hardware come i

processori PowerPC o i processori x86, nonostante Apple abbia annunciato la transizione

di Mac OS X su piattaforme x86 solo nel 2005.

Per sua costruzione il Mach è identificato come un sistema microkernel7. Xnu però non lo

6 Il kernel Debugger di basso livello integrato nello XNU si chiama KDB (o DDB). È implementato nella porzione

Mach del Kernel, così come KDP che è il protocollo remoto di debugging del Kernel usato dal debugger GNU

(GDB). 7 Fu realmente un microkernel solo dalla versione 3. Nelle versioni precedenti aveva un'implementazione monolitica

in cui BSD e Mach occupavano lo stesso spazio di indirizzi.

Page 31: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

31

utilizza come un microkernel tradizionale, nonostante l'implementazione utilizzata dalla

Apple derivi dalla versione 3. Vari sottosistemi che sarebbero implementati come server

nello user-space di un vero sistema microkernel, sono parti proprie del kernel nel Mac OS

X. In particolare la porzione BSD dello XNU, l'I/O Kit ed il Mach risiedono nello stesso

spazio degli indirizzi: tuttavia hanno responsabilità ben definite che li separano in termini

di funzioni ed implementazioni.

2.5.1.2 BSD

Il kernel XNU contiene una sostanziale quantità di codice derivante da BSD, tuttavia se

alcune porzioni sono sostanzialmente simili alle originali, molte altre sono abbastanza

differenti per permettere l'interazione con entità estranee a BSD, come ad esempio l'I/O

Kit ed il Mach.

Le funzioni di cui BSD è responsabile sono:

• Il modello dei processi nello stile BSD

• I segnali

• Gli user Ids, i permessi e le politiche base della sicurezza

• Le APIs del POSIX

• Le APIs di I/O asincrono

• Le chiamate di sistema nello stile BSD

• Lo stack TCP/IP, i socket BSD ed il firewalling

• Le Network Kernel Extensions (NKEs)8

• Lo strato VFS (Virtual File System) e numerosi file system, incluso un meccanismo di

journaling a livello VFS indipendente dal file system.

• I meccanismi IPC del System V e del POSIX

• Una struttura crittografica intra-kernel

8 Si tratta di un tipo particolare di estensioni del kernel che rendonol'architettura networking di BSD pienamente

compatibile con XNU.

Page 32: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

32

• Un sistema di notifiche (basato sul meccanismo kqueque/kevent del FreeBSD), un

servizio a livello di sistema che abilita notifiche tra applicazioni e dal kernel alle

applicazioni

• Il meccanismo di notifica del cambio di file system fsevent (utilizzato in Mac OS X

dalla tecnologia di ricerca Spotlight)

• Le liste di controllo degli accessi e la struttura d'autorizzazioni kauth, una struttura

estensibile di autorizzazioni a carattere generale.

Alcune funzionalità del kernel hanno implementazioni a basso livello in una porzione del

kernel con strati d'astrazione d'alto livello in un'altra porzione. Per esempio la tradizionale

struttura dei processi (struct proc), che è la struttura dati primaria del kernel rappresenta

un processo UNIX, è contenuta nella porzione BSD come la u-area9.

Nel Mac OS X non è eseguito nessun processo BSD: esso coincide con un task Mach che

contiene uno o più thread Mach e sono questi thread ad essere eseguiti. Consideriamo ad

esempio la chiamata di sistema fork() che, a meno di varianti come vfork(), è il solo modo

per creare un nuovo processo in un sistema UNIX. In Mac OS X i task ed i thread son

creati e manipolati attraverso delle “Mach calls”, che l'utente non utilizza direttamente:

l'implementazione BSD-style della fork utilizza queste chiamate per creare un task ed un

thread. Dal punto di vista del chiamante la fork(), questa appare atomica e con le strutture

dati Mach e BSD-style sincronizzate.

Similmente la UBC (Unified Buffer Cache) del BSD si aggancia al sottosistema della

memoria virtuale del Mach. La UBC permette al file system ed al sottosistema della

memoria virtuale di condividere i buffer di memoria del kernel. Ogni memoria virtuale di

un processo contiene in genere una mappa sia della memoria fisica che dei file su disco.

Unificando la buffer cache si ottiene un singolo”deposito” per varie entità, riducendo il

numero di accessi al disco e la quantità di memoria utilizzata.

9 È il nome di strutture contenenti dati per-process o per -thread che è possibile scambiare.

Page 33: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

33

2.5.1.3 Standard I/O (I/O-Kit)

Lo XNU ha un framework orientato agli oggetti per i driver di periferiche chiamato

I/OKit. Tale framework utilizza un ristretto sottogruppo del C++10 come linguaggio di

programmazione. L'implementazione di I/O Kit consiste nelle librerie C++ residenti nel

kernel ed un framework per lo spazio utenti (IOKit.framework). Il framework dello spazio

utente quindi è utilizzato per scrivere programmi user-space che comunicano con l'I/O Kit.

Inoltre l'obbiettivo di utilizzare un framework orientato agli oggetti per i driver di

periferica, è permettere agli sviluppatori di concentrarsi sullo sviluppo di determinate

caratteristiche, senza dover implementare anche quelle comuni a tutte le periferiche.

Bisogna notare inoltre che permette il caricamento dinamico dei driver, gestisce le

periferiche hot-plug ed autoconfigurabili. La maggioranza dei driver sono scritti per essere

eseguiti nello spazio utente in modo da migliorare la sicurezza del sistema in quanto il

fallimento di un driver eseguito nello spazio utente non è in grado di bloccare il kernel.

L'architettura runtime dell'I/O Kit è modulare ed a strati. Fornisce un'infrastruttura per

catturare, rappresentare e mantenere relazioni tra varie componenti hardware e software

che sono coinvolte nelle connessioni I/O. In questo modo l'I/O Kit presenta delle

astrazioni dell'hardware sottostante al resto del sistema.

2.5.2 Inter Process Comunication (IPC)

Il Kernel Mach consente la creazione e la soppressione di più task, che sono simili ai

processi ma hanno più thread di controllo. La maggior parte delle comunicazioni si

compie per mezzo di messaggi (IPC), i messaggi si inviano e si ricevono attraverso porte.

Nel seguito descriveremo le caratteristiche dei thread, task, porte e messaggi.

2.5.2.1 Task e Thread

Il Mach divide le astrazioni tradizionali dei processi UNIX in due parti: un task ed un

10 Tale sottoinsieme non include caratteristiche che Apple ritiene siano rischiose in un kernel multithread (eccezioni,

ereditarietà multipla, i modelli, run-time type information).

Page 34: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

34

thread. Nel Mac OS X, i termini “thread” e “process” hanno delle connotazioni specifiche

a seconda del contesto ovvero dell'ambiente user-space. All'interno del kernel, un processo

BSD (analogo ad un tradizionale processo UNIX), è una struttura dati con una

corrispondenza 1-a-1 verso un task Mach.

Un task del Mach ha le seguenti caratteristiche fondamentali:

• È un ambiente d'esecuzione ed un'entità statica. Ciò vuol dire che non esegue

operazioni, ma fornisce una struttura tale da permettere ad altre entità (thread) di

eseguire operazioni.

• È l'unità base dell'allocazione delle risorse. Un task contiene quindi una collezione di

risorse come accesso ai processori, spazio di indirizzi virtuali paginato, spazio IPC,

gestori delle eccezioni, credenziali, descrittori di file, stato della protezione, stato della

gestione dei segnali e statistiche. Notiamo inoltre che le risorse del task includono

oggetti UNIX, che in Mac OS X sono contenuti in un task mediante la sua

corrispondenza 1-a-1 con la struttura del processo BSD.

• Rappresenta il contorno di protezione di un programma. Un task non può accedere alle

risorse di un altro task senza aver ottenuto una esplicita autorizzazione.

• Un thread è l'attuale entità di esecuzione nel Mach ed è un punto di controllo di flusso

all'interno di un task. Ha le seguenti caratteristiche:

• Esegue all'interno di un task, rappresentando un program counter indipendente nel task.

Un thread è anche l'unità schedabile fondamentale, ogni thread quindi è schedato pre-

ventivamente ed indipendentemente sia dai thread dello stesso task che da quelli di altri

task.

• Il codice eseguito da un thread risiede nello spazio degli indirizzi del proprio task.

• Ogni task può contenere nessuno o più thread, ma ogni thread deve riferirsi ad un unico

task. Si noti comunque che un task senza thread, pur esistendo non può andare in

esecuzione.

• Tutti i thread di un task condividono le risorse del task stesso. Ciò vuol dire che

Page 35: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

35

condividendo anche la memoria, è possibile che un thread sovrascriva la memoria di un

altro thread, senza per altro dover ottenere privilegi aggiuntivi. Poiché ci possono

essere numerosi thread all'interno dello stesso task, tali thread devono cooperare.

• È possibile che un thread abbia il proprio gestore delle eccezioni.

• Ogni thread ha un proprio stato di computazione, quindi i registri di processore, un

program counter ed uno stack. Poiché abbiamo detto che le risorse sono condivise tra i

thread dello stesso task, ogni thread può accedere agli stack degli altri thread dello

stesso task.

• Per amministrare le chiamate di sistema un thread utilizza uno stack del kernel di 16k

di dimensione.

È possibile quindi riassumere un task come passivo, con risorse proprie e come unità base

della protezione. Invece è possibile definire un thread come attivo, che esegue istruzioni

ed è l'unità base del controllo di flusso. Da tutte queste considerazioni è intuibile che

creare o distruggere un task è notevolmente più costoso che creare e distruggere un thread.

Al contrario dei processi UNIX, non si mantiene una relazione tra un task Mach ed il suo

task creatore. Relazione che ovviamente esiste tra il thread ed il suo task contenitore. Ad

ogni modo il kernel mantiene le relazioni padre-figlio a livello di processo nelle strutture

BSD. Tuttavia è anche possibile considerare una relazione padre-figlio anche per i task, in

quanto un task generato eredita alcuni aspetti del “task padre”, come le porte registrate, le

porte eccezioni e botstrap, token di verifica e sicurezza, regioni di mapping condivise e set

di processori. Notiamo inoltre che se il task padre è marcato come inattivo, il figlio è

assegnato al processor set di default.

Una volta creato un task, chiunque con un valido identificatore di task (e gli appropriati

diritti ad una porta IPC Mach) può compiere operazioni sul task. Un task può inoltre

spedire il proprio identificatore ad un altro task in un messaggio IPC, se lo desidera.

Il kernel utilizza questa struttura di task e thread per dividere le proprie funzionalità in vari

flussi di lavoro, utilizzando un singolo task (il kernel task) con thread multipli per svolgere

Page 36: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

36

le operazioni del kernel stesso. È possibile quindi descrivere XNU come un kernel

monolitico, contenente componenti marcatamente differenti (Mac, BSD, I/O Kit) che

girano tutti come gruppi di thread all'interno di uno stesso task, condividendo lo stesso

spazio di indirizzi.

2.5.2.2 Porte

Una porta Mach è un'astrazione con varie sfaccettature implementata come una coda a

lunghezza finita di messaggi. Oltre alle porte Mach, il Mac OS X fornisce altri

meccanismi IPC, sia nello spazio kernel che in quello utente. Possiamo elencare ad

esempio le IPC del Posix e del System V, il descriptor passing, le notifiche multiple e gli

Apple Events.

Ogni porta ha dei diritti associati (right). Tali diritti sono gestiti dal kernel e devono essere

posseduti dal task che voglia gestire tale porta. I right determinano quali task possono

inviare messaggi ad una porta e quale task può ricevere i messaggi attribuiti alla porta. È

da notare comunque che mentre è possibile per più task inviare messaggi ad una stessa

porta, soltanto uno più ricevere messaggi da essa.

Nell'approccio orientato agli oggetti, una porta è un riferimento ad un oggetto, svariate

astrazioni del Mach quindi sono rappresentate da porte. In tal senso una porta funziona

come un provider di accesso protetto ad una risorsa di sistema. Ogni task o thread quindi è

accessibile tramite porte, task port o thread port. Ognuno di questi accessi richiede una

capacità (capability) della porta, vale a dire il diritto di mandare o ricevere messaggi da

quella porta e quindi l'oggetto che la porta rappresenta. Ogni oggetto può avere più porte

da cui ricevere messaggi per differenziare livelli di accesso o funzionalità. L'oggetto che

detiene i diritti di ricezione da una porta può quindi ricevere il messaggio, processarlo ed

eventualmente effettuare un'operazione richiesta nel messaggio. Ogni task, come ogni

thread al suo interno, ha un exception port. Ad esempio un gestore degli errori può

registrare una delle sue porte come un exception port di thread. Quando avviene

Page 37: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

37

un'eccezione, un messaggio può essere inviato a tale porta ed il gestore può riceverlo e

processarlo.

Poiché tutti i thread hanno in comune il task, questi possono accedere a tutte le porte del

task stesso. Allo stesso tempo, tramite il passaggio di diritti attraverso messaggi IPC, è

possibile che un task dia la possibilità ad un altro task di accedere alle proprie porte. Le

porte inoltre possono essere raggruppate in un port set. Pur condividendo un ricevitore e la

coda di messaggi, è possibile inviare il messaggio alla singola porta del set.

Notiamo inoltre che per un sistema Mach, le porte sono progettate per essere trasparenti

alla rete, permettendo ai task di comunicare tra le macchine della rete senza preoccuparsi

di sapere la collocazione delle porte stesse. Tale meccanismo è garantito da un server

centrale per lo scambio di messaggi. Tale approccio ad un sistema di IPC distribuito però

non è implementato in Mac OS X, che lo rende comunque possibile attraverso meccanismi

di alto livello come l'API Distribuited Objects del Cocoa.

Notiamo inoltre che una porta può essere utilizzata solo per mandare messaggi in un'unica

direzione, quindi non rappresenta l'end point di una comunicazione bidirezionale, al

contrario del Socket BSD.

2.5.2.3 Messaggi

I messaggi IPC del Mach sono data object che i thread si scambiano per comunicare.

Tramite messaggi quindi avviene anche la comunicazione tra il kernel ed i task utente. Un

messaggio inoltre può contenere dati in-line oppure puntatori a dati out-of-line (OOL). Da

notare è che il trasferimento di dati OOL è una ottimizzazione per i grandi trasferimenti, il

kernel infatti alloca una regione di memoria per il messaggio nello spazio degli indirizzi

del ricevente, senza creare una copia fisica del messaggio. Un messaggio può contenere

dati arbitrari di programma, copia di blocchi di memoria, eccezioni, notifiche, capacità di

porta e così via. In particolare l'unico modo per trasferire le capacità di porta da un task ad

un altro è attraverso messaggi.

Page 38: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

38

I messaggi Mach sono trasferiti in modo asincrono. Anche se un solo task può usufruire

dei diritti di ricezione di una porta, molti threads in un task possono cercare di ricevere

messaggi su una porta, in questo caso solo uno dei threads avrà successo nella ricezione.

2.5.3 Bonjour e servizi DNS

Bonjour è un marchio registrato usato da Apple per denominare la sua implementazione

del protocollo Zeroconf dell'IETF, una tecnologia basata sulle reti locali introdotta dalla

versione 10.2 di Mac OS X. Questa tecnologia usa il pacchetto standard DNS in un modo

nuovo, sviluppa cioè dei nuovi servizi utilizzando una tecnologia relativamente vecchia

come quella del DNS over IP. Inizialmente la tecnologia sviluppata da Apple utilizzava il

nome Rendezvous ma, per motivi legali, con la versione 10.4 del suo sistema operativo

Apple ha rinominato la tecnologia con il nome di Bonjour.

2.5.4 Protezione delle risorse condivise

Per consentire un funzionamento sicuro su macchine multiprocessore l'accesso alle risorse

condivise (file, strutture dati, ecc) sono serializzati in modo da impedire ai processi di

modificare la stessa risorsa nello stesso tempo. Le operazioni atomiche, spinlock, sezioni

critiche, sistemi a mutua esclusione e gestione serializzata sono i possibili metodi per

impedire accessi pericolosi a strutture condivise. Inoltre, come Linux e FreeBSD, Darwin

implementa sistemi a mutua esclusione (mutex) a grana fine per ottenere elevate

prestazioni nei sistemi multiprocessore.

Page 39: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

39

Capitolo 3 Strumenti di sviluppo per iPhone

3.1 Introduzione all'ambiente Cocoa

Cocoa è un framework object-oriented che fornisce un ambiente runtime per applicazioni

eseguibili in Mac OS X e per sistemi che utilizzano tecnologie multi-touch, come l'iPhone

ed iPode touch. Cocoa quindi fornisce supporto agli sviluppatori dalla fase di design

all'implementazione dell'applicazione stessa.

Xcode (Apple, The development Environment) è invece un ambiente integrato di sviluppo

software che permette di sviluppare applicazioni sia per Mac OS X che per iPhone OS, la

combinazione di questo ambiente di sviluppo e di Cocoa facilita lo sviluppo di

applicazioni molto articolate.

Come tutti gli ambienti di sviluppo, Cocoa è composto da due parti: ambiente di runtime

ed ambiente di sviluppo. Nell'ambiente di runtime le applicazioni hanno un'interfaccia

utente ben integrata con le altre parti del sistema operativo per il quale vengono

sviluppate, ad esempio risultano, in Mac OS X, ben integrate con il Finder, il Dock e le

altre peculiarità del sistema stesso.

L'aspetto più interessante di Cocoa è l'ambiente di sviluppo. Cocoa è una suite integrata di

componenti software object oriented che permettono di creare rapidamente software

robusti e ricchi di caratteristiche, grazie alle classi (componenti) che possono essere

riutilizzate, modificate ed adattate alle necessità richieste dal software. Le classi Cocoa

esistono per quasi tutte le necessità di sviluppo, dalle interfacce utente alla formattazione

dei dati e nel caso sia necessario è possibile creare agevolmente sottoclassi. È importante

notare che Apple consiglia vivamente di sfruttare le classi e gli oggetti forniti da Cocoa, in

quanto restituisce agli utenti uniformità tra i software sviluppati, sopratutto per quanto

riguarda l'approccio alle interfacce grafiche.

Cocoa è un ambiente con cui è possibile sviluppare (limitatamente a Mac OS X), oltre ad

applicazioni, anche strumenti da riga di comando, plug-ins e qualunque tipo di software.

Page 40: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

40

E' possibile utilizzare diversi linguaggi di programmazione, anche se il linguaggio

privilegiato è Objective-C. Inoltre è possibile richiamare dal codice, interfacce di

programmazione non Cocoa, come la libreria di interfacce BSD (/usr/include); è possibile

anche mescolare codice C++ con codice Cocoa e collegarli nello stesso eseguibile.

Per lo sviluppo di applicazioni in Mac OS X è possibile sviluppare utilizzando bridge

come PyObjC (il bridge Python–Objective-C) e RubyCocoa (il bridge Ruby–Cocoa). Tali

bridge permettono di scrivere applicazioni cocoa nei rispettivi linguaggi, Python e Ruby,

interpretandoli e creando oggetti, in modo da poter comunicare con gli oggetti object-C

nativi dell'ambiente Cocoa.

Il cuore delle librerie di classi Cocoa (Cocoa Touch) è impacchettato in due framework

principali, Foundation ed Application Kit per Mac OS X e Foundation ed UIKit per

iPhone OS. Come tutti i Framework, non includono solo librerie dinamiche condivise, ma

header file, Documentazione API e altre risorse. Entrambi i framework seguono il

principio chiave di Cocoa nel dividere ciò che fa parte dell'interfaccia d'utente e ciò che

non ne fa parte.

3.1.1 Cocoa in Mac OS X

Si consideri il seguente diagramma semplificato di Mac OS X.

In Figura 2 è possibile osservare la struttura semplificata di Mac OS X. Si possono

distinguere i seguenti blocchi:

Figura 2: struttura semplificata

Page 41: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

41

• Carbon è un set di API in C che offre agli sviluppatori un avanzato kit di strumenti per

interfacce utente, gestione degli eventi e supporto multiprocessing. Gli sviluppatori

hanno accesso alle altre API C e C++, incluso il sistema di disegno grafico OpenGL, al

microkernel Mach ed ai servizi BSD del sistema operativo. Tali Api consentono inoltre

a programmi scritti per sistemi Classic Mac OS 8.1 (o precedenti) di funzionare anche

su Mac OS X, quindi garantisce la retrocompatibilità di software esistente. È molto

utile quindi per sviluppare una nuova applicazione o effettuare un porting da un'altra

piattaforma. In ogni caso se si deve sviluppare una nuova applicazione e si desidera

usare un linguaggio orientato agli oggetti, è preferibile utilizzare Cocoa.

• Aqua definisce l'aspetto e le caratteristiche estetiche delle applicazioni in Mac OS X.

Aqua incorpora colori, profondità, colori traslucidi e texture complesse nelle interfacce

grafiche. La funzione di Aqua è quindi rendere coerenza all'aspetto grafico delle

applicazioni, restituendo così familiarità nell'utilizzo da parte degli utenti. Tutte le

applicazioni scritte utilizzando le interfacce di Mac OS X ereditano automaticamente la

caratteristiche Aqua.

• Quartz è un potente sistema grafico che costituisce la struttura dei modelli grafici per

Mac OS X. Quartz offre un sofisticato motore di disegno bidimensionale ed un

avanzato ambiente per la gestione delle finestre per le applicazioni. Inoltre, il motore di

disegno include anche il disegno di Portable Document Format (PDF) ed offre

strumenti di disegno per funzionalità di Mac OS X. I servizi per le finestre offerto da

Quartz forniscono funzionalità di basso livello come buffering delle finestre, creazione

dinamica, ombre, traslucenza ed altri effetti inseriti nelle interfacce grafiche di Aqua.

• OpenGL (Open Graphics Library) è una specifica che definisce una API per più

linguaggi e per più piattaforme per scrivere applicazioni che producono computer

grafica 2D e 3D. È usata principalmente per la programmazione di giochi, animazioni,

CAD/CAM, immagini mediche ed altre applicazioni che visualizzano e manipolano

grafiche 2D e 3D ad alte prestazioni. L'implementazione Apple di OpenGL è stata

Page 42: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

42

ottimizzata per piattaforme Machintosh ed include una suite di estensioni che danno

agli sviluppatori accesso ad avanzate capacità hardware per la grafica.

• QuickTime, le Api Cocoa per QuickTime includono classi per usare applicazioni in

Mac OS X che includono caratteristiche multimediali come video, audio, animazioni,

grafica, testo e funzionalità di interattività. QuickTime supporta la maggior parte dei

formati per immagini, video ed audio, incluso video MPEG-4 ed audio AAC.

• La figura 2 trascura però diverse parti del Sistema Operativo in questione, ma rende

bene l’idea di come Cocoa interagisca con il sistema stesso.

La Figura 3 evidenzia invece come Cocoa sia inserito nell'architettura di sistema. Tale

schema mostra come Mac OS X sia composto da una serie di strati software che partono

dalle radici di Darwin11 ed arrivano fino agli ambienti applicativi. Gli strati intermedi

rappresentano il software di sistema incluso nei due framework principali: Core Services e

Application Services. Come si evince dal grafico ogni componente ha interazione con lo

strato sottostante.

Le due figure sono in sostanza molto simili, ad esempio Quartz (realizzato nel framework

Core Graphics), il componente di sistema che è in gran parte responsabile del rendering

11 Darwin è la tecnologia su cui si basa il Core OS di Mac OS X ed integra diverse tecnologie come descritto nel

paragrafo 5 del capitolo 2.

Figura 3: Architettura di Mac OS X

Page 43: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

43

con l'interfaccia utente Aqua, fa parte dello strato Application Services. Alla base della

struttura c'è Darwin: tutto in Mac OS X, compreso Cocoa, dipende dalle funzioni di

Darwin.

In figura 4 è possibile osservare le classi Cocoa divise in pacchetti, in particolare è

possibile vedere le dipendenze dei subframework di Cocoa dagli altri strati di Mac OS X.

Apple ha progettato Cocoa in modo da permettere, attraverso le sue interfacce, l'accesso

diretto alle tecnologie basilari di cui le applicazioni in genere hanno bisogno. E' possibile

comunque avere controllo anche di funzionalità non supportate dalle interfacce Cocoa, ad

esempio richiamando le funzioni di Core Graphics o quelle di OpenGL. Fortunatamente,

l'uso dei livelli inferiori del framework non è un problema perché le interfacce di

programmazione sono scritte in standard ANSI C.

I principali framework da cui dipende Cocoa o che richiama attraverso le sue classi e

metodi sono i seguenti:

• Core foundation: Molte classi del Framework Foundation sono strettamente legate al

Core Foundation12, il quale, in alcune sue parti è basato su BSD, in altre su di una parte

dello strato Darwin.

12 Core Foundation fa parte del Core Services ed è descritto nel paragrafo 2.1.2

Figura 4:dipendenze dei subframework di Mac OS X

Page 44: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

44

• Carbon: Cocoa accede per diverse esigenze in Carbon, questo perchè molti servizi

Carbon, come system-wide services, si trovano nello strato Core Services ed in

Application Services.

• Core Graphics: Le classi Cocoa di immagini e di disegno sono strettamente basate sul

framework Core Graphics, che implementa Quartz ed il Window Server.

• Launch Services: La classe NSWorkspace realizza i servizi di Launch Services.

Inoltre, Cocoa utilizza le caratteristiche application-registration di Launch Services per

associare le icone alle applicazioni ed ai documenti.

• Print Core: La classe di stampa Cocoa presenta un'interfaccia orientata agli oggetti

verso il sottosistema di stampa.

3.1.2 Cocoa in iPhone OS

Nonostante l'infrastruttura di iPhone OS e la sua interazione con Cocoa siano simili a Mac

OS X, bisogna considerare significative differenze. Confrontando la Figura 5, di iPhone

OS, e figura 2, di Mac OS X, si può notare come la struttura di iPhone è una serie di strati

che vanno da Core OS foundation ad Application Framework, il cui strato più critico per le

applicazioni è UIKit.

Come nella stratificazione di Mac OS X, anche lo strato intermedio di iPhone OS consiste

Figura 5: Stratificazione di iPhone

Page 45: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

45

nelle librerie grafiche ed audio, anche in questo caso ogni strato spesso ha dipendenze

dagli strati inferiori.

In generale possiamo dire che il sistema di librerie e framework di iPhone OS è un

sottoinsieme delle librerie e dei framework di Mac OS X. Ad esempio, non vi è alcuna

necessità di sviluppare applicazioni Carbon in ambiente iPhone OS, così come non vi è

alcuna necessità di accesso da riga di comando (ambiente BSD); non vi sono servizi e

framework di stampa, e QuickTime è assente dalla piattaforma. Tuttavia, a causa della

natura delle periferiche supportate da iPhone OS, vi sono alcuni framework, sia pubblici

che privati, specifici per iPhone OS.

Di seguito saranno descritti i framework che si trovano in ogni strato di iPhone OS:

Core OS: Questo livello contiene il kernel, il file system, infrastruttura di rete, security,

power management, e un certo numero di driver di periferica. Inoltre include la libreria

libSystem, che gestisce le specifiche POSIX / BSD 4.4/C99 API e include API per molti

servizi a livello di sistema.

Core Services: Il framework a questo livello fornisce servizi essenziali (core services),

come la manipolazione delle stringhe, Networking, URL Utilities, gestione dei contatti, e

le preferenze.

Questo strato comprende Core Foundation, un framework che fornisce astrazioni per tipi

di dati comuni (come stringhe e collezioni), consentendo un elevato grado di integrazione

tra object-oriented e codice di procedura.

Media: I servizi ed i framework in questo strato dipendono dal livello Core Services e

forniscono servizi di grafica e servizi multimediali allo strato Cocoa Touch. Comprendono

Core Graphics, OpenGL ES, Core Animation, Core Audio.

Cocoa Touch: Il framework in questo strato supporta direttamente applicazioni basate su

iPhone OS. E' costituito da due framework Objective-C fondamentali per lo sviluppo di

applicazioni in iPhone OS:

• UIKit fornisce gli oggetti da visualizzare nelle interfacce d'utente delle applicazioni e

Page 46: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

46

definisce il comportamento delle applicazioni, compreso la manipolazione degli eventi

ed il disegno.

• Foundation definisce la struttura base degli oggetti, stabilisce il meccanismo per la

loro gestione e fornisce gli oggetti fondamentali per i tipi di dati, collection e servizi del

sistema operativo. Foundation è essenzialmente il gemello del framework Core

Foundation.

Generalmente è possibile, attraverso metodi o funzioni Foundation o IUKit, accedere alle

funzionalità degli strati inferiori del sistema; se invece si ha bisogno di caratteristiche che

non sono risolvibili attraverso quelle API, è possibile scegliere di usare direttamente un

framework di uno strato inferiore. Nonostante UIKit, per esempio, possa gestire il Web Kit

per disegnare i testi, comunque è possibile decidere di accedere direttamente al Core

Graphics per disegnarli in quanto può servire per gestire determinate esigenze. E' possibile

accedere ai framework degli strati inferiori proprio in quanto le interfacce sono scritte in

ANSI C, perfettamente compatibile con Objective-C.

3.2 Ambiente di Sviluppo

L'ambiente di sviluppo per applicazioni Cocoa non è unico, è possibile infatti sia

sviluppare con applicazioni fornite da Apple come Xcode13 ed Interface Builder, che

utilizzare software di terze parti. Ad esempio, per sviluppare software per Mac OS X

basate su Carbon, si può scrivere codice usando un text editor come Emacs, compilare

l'applicazione dalla linea di comando ed utilizzare gdb debugger per il debug

dell'applicazione stessa.

Nonostante ciò, Xcode ed Interface Builder sono le applicazioni più comunemente

utilizzate per sviluppare software Cocoa. Nate insieme a Cocoa stesso, esiste una grande

compatibilità tra tool e framework, facilitando così il disegno, la gestione, la compilazione

13 Xcode è talvolta usato riferendosi all'intera suite di strumenti di sviluppo e framework, altre volte invece, è utilizzato

specificatamente per l'IDE che permette di gestire codice e progetti eseguibili.

Page 47: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

47

ed il debug di progetti software.

3.2.1 Piattaforma SDK

Con l'introduzione di Xcode 3.1 e dell'iPhone OS, per creare un progetto software bisogna

scegliere la piattaforma SDK, che permetterà di costruire software eseguibile per

determinate versioni di Sistemi Operativi o diverse piattaforme, come Mac OS X e iPhone

OS. Mac OS X SDK, ad esempio, è formato da framework, librerie, header file e strumenti

di sistema. L'SDK per iPhone include gli stessi componenti, in più comprende altri tool ed

un compilatore specifico per iPhone, inoltre contiene anche uno specifico ambiente di

simulazione per iPhone OS. L'SDK contiene inoltre diversi template di progetti specifici

per le diverse piattaforme.

3.2.2 Xcode

Xcode è il motore dell'ambiente di sviluppo integrato (IDE) per applicazioni in Mac OS X

ed iPhone OS, inoltre è l'applicazione che cura la maggior parte delle fasi di sviluppo di un

progetto software, dalla fase iniziale fino alla conclusione dello sviluppo.

Xcode permette di:

• Creare e gestire progetti, indicando la piattaforma, i requisiti necessari, le dipendenze e

le configurazioni strutturali

• Scrivere codice in un editor che gode di caratteristiche come la colorazione del codice

ed il rientro automatico

• Navigare e cercare attraverso i componenti di un progetto, incluso gli header file e la

documentazione

• Compilare un progetto

• Effettuare il Debug di un progetto remotamente, o localmente nel simulatore iPhone

OS, in un grafico source-level debugger

Xcode compila progetti da codice sorgente scritto in C, C ++, Objective-C, e Objective-C

++, genera eseguibili e tutti i tipi di software supportati da Mac OS X, compresi strumenti

Page 48: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

48

da riga di comando, framework, plug-in, estensioni del kernel, bundle e le applicazioni.

Per iPhone OS, invece, sono possibili solo applicazioni eseguibili.

Xcode permette una quasi illimitata personalizzazione di strumenti di sviluppo e debug,

packaging di eseguibili, costruzione di procedure (compresi i copy-file, script-file, ed altre

fasi di costruzione del progetto), e dell'interfaccia utente (compreso un editor separato di

codice multi-view). Supporta inoltre molti sistemi di gestione del codice sorgente, come

CVS, Subversion e Perforce, che permettono di caricare il codice in un repository,

effettuare modifiche, aggiornare le versioni e confrontarle.

Xcode, essendo specifico per sviluppare applicazioni Cocoa, permette di scegliere, alla

creazione di un progetto, a quale template far riferimento, applicazioni, tool, bundle,

framework o altri. Per compilare applicazioni per Mac OS X, Xcode usa GNU C compiler

(gcc) e per debugging utilizza GNU source-level debugger (gdb); inoltre è ben integrato

con Interface builder, applicazione di sviluppo per interfacce.

3.2.3 Flusso di lavoro

La differenza nello sviluppo di applicazioni per Mac OS X e per iPhone OS non è negli

strumenti ma nel flusso di lavoro dello sviluppo. In Mac OS X uno sviluppo tipico segue il

flusso descritto in seguito:

• Creare un progetto in Xcode usando un template di Mac OS X SDK.

• Scrivere il codice e, usando Interface Builder, costruire la sua interfaccia d'utente.

• Definire gli obiettivi ed eseguirli nell'ambiente di sviluppo del progetto.

• Testare e effettuare il debug dell'applicazione usando le facilitazioni che Xcode offre;

vedere il debug nella finestra di Console.

• Misurare le prestazioni dell'applicazione usando uno o più strumenti per analizzarla.

In iPhone OS, le fasi dello sviluppo di un'applicazione è leggermente più complicato.

Prima di iniziare comunque è necessario registrarsi come sviluppatore della piattaforma.

Successivamente, lo sviluppo di un'applicazione passa attraverso i seguenti passi:

Page 49: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

49

1. Configurare la periferica, sono necessari quindi strumenti, framework ed altri

componenti installati sulla periferica stessa.

2. Creare un progetto in Xcode usando un template da iPhone OS SDK.

3. Scrivere il codice e, usando Interface Builder, costruire la sua interfaccia d'utente.

4. Definire gli obiettivi ed eseguirli nell'ambiente di sviluppo del progetto.

5. Compilare l'applicazione.

6. Testare ed effettuare il debug dell'applicazione localmente in iPhone OS Simulator

oppure remotamente sul dispositivo, in questo caso il debug dell'eseguibile sarà sul

dispositivo stesso, sarà anche possibile vedere il debug nella finestra di Console.

7. Misurare le prestazioni dell'applicazione usando uno o più strumenti.

3.2.4 Interface Builder

La seconda grande applicazione di sviluppo per progetti Cocoa è Interface Builder (Apple,

The development Environment), uno strumento grafico per la creazione di interfacce

utenti. Tale strumento è anche utile per creare interfacce utente per applicazioni Carbon in

Mac OS X.

I quattro principali elementi di design su cui è centrato Interfacce Builder sono:

Nib file. Un Nib file è un file contenitore (una directory trasparente) che contiene gli

oggetti che compaiono nell'interfaccia utente in una forma di archivio. In sostanza, questo

archivio è un oggetto grafico che contiene informazioni su ogni oggetto, compresa la

dimensione e la posizione, informazioni sui collegamenti tra gli oggetti e sulle classi

personalizzate. Quando si crea e si salva un'interfaccia utente di Interface Builder, tutte le

informazioni necessarie per ricreare l'interfaccia sono memorizzate nel nib file.

Nib file offre un modo semplice per localizzare le interfacce di utente. Interface Builer

infatti registra il nib file nel progetto Cocoa, quando tale progetto sarà compilato il nib file

sarà copiato nella locazione corretta all'interno del pacchetto creato.

Interface Builder visualizza il contenuto del nib file in una finestra del documento (nib file

Page 50: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

50

windows), tale finestra permette di accedere agli oggetti del nib file, soprattutto a quelli

principali come finestre, menu, e objects controller, che collegano gli oggetti delle

interfacce di utente con i modelli di oggetti che rappresentano i dati delle applicazioni,

inoltre forniscono gestione globale dell'applicazione da sviluppare.

Object library. La finestra Library di Interface Builder contiene gli oggetti che

l'interfaccia utente può contenere, comprende sia gli oggetti tipici (come finestre, controlli,

menu, text view) che i controller di oggetti, viste personalizzate di oggetti, oppure

framework come Image Kit. Library raggruppa oggetti per categorie permettendo di

navigare al loro interno cercando oggetti specifici. Trascinando un oggetto dalla library su

di un'interfaccia Interface Builder crea un'istanza predefinita di tale oggetto in modo da

poterlo ridimensionare, configurare e collegarlo ad altri oggetti utilizzando la finestra

Inspector. (che diremo l'Inspector)

Page 51: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

51

Inspector. Interface Builder ha la finestra Inspector associata agli oggetti dell'interfaccia

utente. Inspector include alcuni riquadri selezionabili per impostare la configurazione

iniziale di runtime degli oggetti (anche se le dimensioni ed altri attributi possono essere

manipolati direttamente). L'Inspector, in Figura 6, mostra gli attributi primari per il campo

testo, le varie sezioni racchiuse nell'etichetta permettono di settare altri parametri a vari

Figura 6: Inspector

Page 52: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

52

livelli gerarchici. Oltre alle caratteristiche primarie degli oggetti è possibile tramite

Inspector selezionare effetti animati, gestire eventi AppleScript e vincolare gli oggetti con

meccanismi target-action. Tali meccanismi infatti vengono utilizzati da Cocoa per collegare

controlli dell'interfaccia grafica con oggetti del software che si sta sviluppando. In sostanza

è un tipo di comunicazione utilizzata all'interno delle interfacce grafiche per interpretare gli

input degli utenti e collegare tali controlli ad azioni progettate nel software. Tale sistema

risulta infatti più efficiente di altri meccanismi di comunicazione previsti dalla

programmazione classica (ad esempio notifiche, binding e delegati).

Connections panel. Connection Panel (Figura 7) è un pannello che permette di

visualizzare le connessioni legate ad un oggetto selezionato con il tasto destro nella finestra

di Interface Builder, riferita alla View da modificare. È possibile quindi, attraverso questo

pannello, visualizzare e gestire tutte le connessioni dell'oggetto selezionato.

Interface Builder è perfettamente integrato con Xcode, questo significa che conosce le

azioni, le proprietà e le classi utilizzate. Tale integrazione permette ad Interface Builder di

identificare eventuali modifiche al codice del progetto e riportarle così nell'interfaccia

d'utente.

Figura 7: Connection Panel

Page 53: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

53

3.2.5 The iPhone OS Simulator

Per i progetti iPhone OS è possibile utilizzare iPhone Simulator come piattaforma SDK.

Quando si compila e si esegue un progetto, Xcode avvia il simulatore che visualizza

l'applicazione come se fosse sul dispositivo e abilita l'utilizzo dell'interfaccia utente, è

anche possibile utilizzare il Simulatore per il debug delle applicazioni prima di installare il

software nella periferica.

Bisogna sempre testare il software sul simulatore tenendo presente che non può

rappresentare perfettamente il dispositivo: il mouse ad esempio sostituirà il Touch

rendendo impossibile quindi l'utilizzo di interfacce Multitouch. Inoltre il simulatore non

usa versioni di OpenGL framework specifiche per iPhone OS, ma usa versioni per Mac

OS X di Foundation, Core Foundation, e CFNetwork frameworks, come la versione di

libSystem per Mac OS X.

E' importante inoltre non paragonare le prestazioni dell'applicazione sul simulatore

rispetto a quelle sul dispositivo, il simulatore infatti esegue le applicazione come fossero

applicazioni ospiti di Mac OS X, quindi avranno a disposizione una partizione di memoria

di 4 giga e lo spazio disponibile è quello che avrebbe a disposizione un processo,

prestazioni quindi sensibilmente superiori a quelle ottenute sul dispositivo reale.

3.2.6 Prestazioni delle Applicazioni e Tool

Anche se Xcode ed Interface Builder sono i principali strumenti utilizzati per lo sviluppo

di software Cocoa, ci sono decine di altre applicazioni utili, ad esempio gli strumenti per

diagnosticare le prestazioni delle applicazioni.

3.2.6.1 Instruments

Page 54: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

54

Instruments è un'applicazione introdotta in Xcode 3.0 che permette di utilizzare molteplici

tester di performance simultaneamente e permette di visualizzare i risultati in grafici in

funzione del tempo. E' possibile visualizzare l'utilizzo della CPU, scrittura e lettura su

disco, memoria utilizzata, attività dei thread, statistiche di rete, utilizzo di file e cartelle ed

altre misurazioni, con la possibilità di combinarle in grafici in funzione del tempo. La

rappresentazione simultanea dei diversi dati rilevati permette di scoprire le relazioni tra ciò

che si è misurato.

3.2.6.2 Shark

Shark è un'applicazione di analisi delle performance, crea un profilo time-based dei

software in esecuzione. In una finestra temporale, infatti, traccia il grafico dell'allocazione

in memoria delle applicazioni. Shark permette di tracciare informazioni per una singola

applicazione o di tutto il sistema, in Mac OS X è possibile includere i componenti del

Figura 8: Instruments Window

Page 55: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

55

kernel come driver ed estensioni del kernel stesso. Inoltre, è possibile tramite Shark

monitorare le chiamate al file system, tracciare le chiamate di sistema e l'allocazione della

memoria, analisi statiche del codice e raccoglie informazioni su cache misses, page fault

ed altre metriche di sistema. Infine, Shark supporta l'analisi di codice scritto in C,

Objective-C, C++ ed altri linguaggi.

3.2.6.3 Altre applicazioni per le prestazioni (Mac OS X)

Molte altre applicazioni sono utili alla misurazioni ed analisi delle performance di

applicazioni per Mac OS X. Alcuni esempi sono:

• Thread Viewer visualizza l'attività di comunicazione tra i thread di un processo,

visualizzando su di una linea temporale l'attività di ogni thread e colorando

diversamente ogni azione. Selezionando una time-line è possibile prendere un

campione dell'attività in quel punto.

• BigTop visualizza in un grafico il trend delle prestazioni nel tempo, visualizzando in

tempo reale l'uso della memoria, i page faults, l'uso della CPU ed altri dati.

• Spin Control campiona automaticamente le mancate risposte dell'applicazione.

Lasciando in background Spin Control mentre l'applicazione è in esecuzione, nel

momento in cui, dopo un determinato input, non si riceve risposta dal software appare il

cursore di spinning, e Spin Control campiona automaticamente l' applicazione,

raccogliendo le informazioni su cosa sta facendo all'applicazione in esecuzione.

• MallocDebug visualizza tutti i blocchi allocati dell'applicazione, organizzati in

funzione dello stack al momento dell'allocazione; è possibile quindi osservare il

consumo di memoria dell'applicazione in esecuzione, dove vengono allocati i blocchi e

quale funzione alloca più memoria. MallocDebug aiuta a trovare memoria allocata che

non è puntata nel software, aiutando così a rintracciare dove la memoria viene allocata.

• QuartzDebug è uno strumento di aiuto per come si visualizza il debug delle

applicazioni. Esso è utile per applicazioni che hanno un gran numero di disegni ed

Page 56: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

56

immagini, gestendo numerose opzioni di debug.

3.3 Cocoa Framework

Prima di studiare il framework Cocoa è necessario osservare che le applicazioni Cocoa

non sono basate tutte sullo stesso linguaggio perchè possono essere scritte in diversi

linguaggi e non hanno in comune i software di sviluppo in quanto è possibile compilarli e

scriverli da riga di comando. Possiamo quindi affermare che le applicazioni Cocoa hanno

in comune l'essere composte da oggetti ereditati dalla classe principale NSObject e sono

basati su runtime Objective-C. Questo vale per tutti i framework Cocoa. Bisogna

comunque sottolineare che Foundation Framework prevede anche un'altra classe di root,

NSProxy, ma questa viene utilizzata raramente nello sviluppo di applicazioni Cocoa.

Inoltre, si deve sottolineare che è possibile costruire una classe principale personalizzata,

ma richiede molto lavoro, dovendo scrivere codice che interagisce con il runtime

l'Objective-C.

Sono diversi i framework sviluppati per applicazioni Cocoa, sia Apple che di terze parti,

ma in sostanza è possibile affermare che soltanto due sono i framework essenziali nello

sviluppo di applicazioni. Tali framework si differenziano per Mac OS X ed iPhone OS e

sono:

1. Per Mac OS X: Foundation ed Application Kit

2. Per iPhone OS: Foundation ed UIKit

I framework Foundation, Application Kit, e UIKit sono essenziali nello sviluppo Cocoa,

tutti gli altri framework sono invece di supporto allo sviluppo. Infatti, non è possibile

sviluppare un'applicazione Cocoa per Mac OS X senza collegarsi (ed usare classi) di

Application Kit, come non è possibile sviluppare applicazioni per iPhone OS senza

collegarsi a UIKit. Allo stesso tempo, non è possibile sviluppare alcuna applicazione senza

utilizzare classi del framework Foundation. Il collegamento al giusto framework su Mac

OS X avviene automaticamente appena ci si collega ad uno dei framework Cocoa per Mac

Page 57: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

57

OS X. Inoltre, bisogna notare che funzioni, tipi di dato e costanti in Foundation ed in

Application Kit hanno “NS” come prefisso, in UIKit hanno invece “UI” come prefisso.

Nella versione 10.5 di Mac OS X, inoltre, il framework Cocoa supporta l'indirizzamento a

64 bit, come iPhone OS. Tale risultato è stato ottenuto sopratutto modificando le API

Cocoa, le modifiche più significative riguardano l'introduzione dei tipi NSInteger e di

NSUInteger, in luogo di insigned int e di tipi CGFloat.

Per conoscere bene l'ambiente iPhone OS è necessario approfondire anche l'ambiente Mac

OS X, in quanto iPhone OS è un sottoinsieme delle sue librerie e della sua struttura. Di

conseguenza per conoscere UIKit è necessario soffermarsi anche su Application Kit. In

iPhone OS, lo strato Cocoa Touch comprende i framework Foundation e UIKit.

3.3.1 Foundation

Il framework Foundation definisce uno strato base di classi che possono essere usate per

ogni tipo di software Cocoa. Il criterio con cui una classe appartiene a Foundation

piuttosto che ad Application Kit è legato all'interfaccia. In sostanza, se un oggetto non

appare nell'interfaccia di utente o non è esclusivamente usato a supporto dell'interfaccia di

utente, significa che appartiene a Foundation. Inoltre, è possibile creare software Cocoa

utilizzando solo Foundation senza altri framework, ad esempio per strumenti a riga di

comando o per server Internet.

Gli scopi per cui è stato pensato Foundation sono:

• Definire il comportamento di oggetti basilari introducendo convenzioni coerenti per più

caratteristiche, come la gestione della memoria, mutabilità degli oggetti e notifiche

• Supporto all'internazionalizzazione ed alla localizzazione attraverso tecnologie bundle

e stringhe Unicode

• Fornire supporto alla persistenza degli oggetti

• Fornire supporto agli oggetti distribuiti

• Fornisce misure di indipendenza dal Sistema Operativo, orientato alla portabiltà

Page 58: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

58

• Offrire oggetti wrapper (o simili) per la programmazione di primitive, come valori

numerici, stringhe e collection. Inoltre, include classi per accedere ai servizi sistema di

base come porte, threads e file system

Le applicazioni Cocoa, che per definizione devono essere collegate al framework

Application kit oppure al UIKit, devono essere ben collegate anche al framework

Foundation. Nella gerarchia delle classi hanno la stessa classe fondamentale, NSObject, e

molti metodi e funzioni di Application Kit e UIKit hanno oggetti di Foundation come

valori di ritorno dei parametri. Molte classi di Foundation possono inoltre sembrare

costruite per le applicazioni, ad esempio NSUndoManager e NSUserDefaults, ma sono

incluse in Foundation perchè il loro utilizzo non coinvolge l'interfaccia grafica dell'utente.

3.3.1.1 Foundation: paradigmi e politiche

Foundation introduce politiche e paradigmi per la programmazione Cocoa, al fine di

garantire coerenza nel comportamento degli oggetti di un programma in determinate

situazioni. Questi includono:

Mantenimento e rilascio di oggetti. Il runtime Objective-C e Foundation offrono ai

programmi Cocoa due metodi per garantire il mantenimento degli oggetti quando servono

ed il loro rilascio quando non è più necessario mantenerli. Tali metodi sono Garbage

Collection (non supportato da iPhone OS) e Memory Management. Garbage Collection,

introdotto in Objective-C 2.0, automaticamente si disfa delle tracce di cui non ha più

bisogno, in modo da liberare memoria. Memory anagement, invece, istituisce una politica

di proprietà degli oggetti, ritiene in sostanza gli oggetti responsabili del rilascio di altri

oggetti che hanno creato, copiato o esplicitamente trattenuto.

E' da notare che in iPhone OS, per motivi di prestazioni, Garbage Collection non è

abilitato nelle applicazioni Cocoa. Memory Management comunque è descritto nel

paragrafo 4.3.4.1

Mutable class variants. In Foundation, molti valori e contenitori di classi sono varianti di

Page 59: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

59

classi immutabili. Ogni classe mutevole è sempre una sottoclasse di una immutabile. Se

bisogna cambiare dinamicamente un valore incapsulato o associato ad un oggetto, è

possibile creare un'istanza di una classe mutevole; poiché è ereditato da una classe

immutabile, è possibile passare l'istanza mutevole in metodi mutuati dai type immutabili.

Class clusters. Una Class Cluster è una classe astratta ed un set privato di sottoclassi per

le quali la classe astratta agisce da interfaccia come un ombrello. In funzione del contesto

(in particolare dal metodo che si utilizza per creare un oggetto) restituisce un'istanza o una

sottoclasse ottimizzata appropriatamente. Struttura Gerarchica è descritta nel paragrafo

4.4.9.1.

Notifications. Notification è uno dei principali modelli di progettazione in Cocoa, è basato

su di un meccanismo di broadcast che permette agli oggetti, detti osservatori, di prendere

informazioni su cosa un altro oggetto sta facendo o a quali eventi di sistema o dell'utente

sta andando incontro. L'oggetto osservato può non essere a conoscenza dell'esistenza e

dell'identità dell'osservatore. Ci sono diversi tipi di notifiche: sincrona, asincrona e

distribuita. Il meccanismo di notifica di Foundation è implementato dalle classi

NSNotification, NSNotificationCenter, NSNotificationQueue, e

NSDistributedNotificationCenter.

3.3.1.2 Classi Foundation

La gerarchia delle classi Foundation, hanno radice nella classe NSObject, che (insieme ad

i protocolli NSObject e NSCopying) definisce gli attributi ed il comportamento degli

oggetti base.

Il resto del framework Foundation è composto da diversi gruppi di classi, più qualche

classe individuale. Ci sono classi che rappresentano tipi di dato basilari, come stringhe e

array di bit, collezioni di classi per registrare altri oggetti, classi per rappresentare

informazioni di sistema come date, oppure classi per rappresentare entità di sistema come

porte, thread e processi. La gerarchia di classi rappresentate in figura 9, 10 e 11 descrivono

Page 60: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

60

la divisione in gruppi e la gerarchia associata alle classi. Le classi nelle aree blu sono

quelle condivise dalle versioni Foundation di Mac OS X ed iPhone.

Le figura 9, 10 e 11 raggruppano le classi del framework Foudation nelle seguenti

categorie:

Page 61: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

61

Figura 9: Foudation Framework (1)

Page 62: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

62

Figura 10: Foundation Framework (2)

Page 63: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

63

Figura 11: Foundation Framework (3)

Page 64: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

64

Value objects. Value object include dati di vari tipi, restituisce accesso ai dati ed offre vari

tipi di manipolazione degli stessi, inoltre, in quanto oggetti, possono essere archiviati e

distribuiti. NSData fornisce una memorizzazione orientata agli oggetti per stringhe di

bytes mentre NSValue la fornisce per array di valori scalari semplici. Le classi NSDate,

NSCalendarDate, NSTimeZone, NSCalendar, NSDateComponents, e NSLocale

forniscono oggetti che rappresentano tempo, date, calendari e Locales. Offrono metodi per

calcolare differenze temporali, per visualizzare date e tempi in diversi formati e per

aggiustare tempo e date in funzione dei fusi orari.

Strings. NSString è un altro tipo di valore che fornisce una memorizzazione orientata agli

oggetti per array di byte null-terminated in particolari codifiche. Include supporto per

conversione di stringhe codificate in UTF-16, UTF-8 e altri tipi di codifiche.

NSString inoltre offre metodi di ricerca, combinazione e comparazione di stringhe e per

manipolazione di percorsi di file system. Gli oggetti NSScanner permettono di analizzare

numeri e word provenienti da un oggetto NSString. NSCharcterSet rappresenta invece un

set di caratteri usati da diversi metodi NSString e NSScanner.

Collections. Un oggetto Collection registra ed utilizza altri oggetti (generalmente valori),

in un particolare ordine. NSArray utilizza un'indicizzazione zero-based, NSDictonary usa

coppie di valori chiave e NSSet memorizza in maniera non ordinata oggetti. Con un

oggetto NSEnumerator è possibile l'accesso sequenziale di elementi di una collezione. Gli

oggetti Collection sono componenti essenziali delle liste di proprietà e, come tutti gli

oggetti, possono essere archiviati e distribuiti.

Servizi Operating-system. Molte classi Foundation facilitano l'accesso a diversi servizi

degli strati inferiori del sistema operativo e, allo stesso tempo, isola lo sviluppatore dalle

idiosincrasie del sistema operativo. Per esempio, NSProcessInfo consente di interrogare

l'ambiente nel quale l'applicazione viene eseguita e NSHost restituisce il nome e l'indirizzo

dell'host nella rete. Un oggetto NSTimer invece invia un messaggio ad un altro oggetto a

Page 65: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

65

determinati intervalli di tempo, NSRunLoop permette di gestire le sorgenti d input di

un'applicazione o altri tipi di programmi. NSUserDefaults fornisce un'interfaccia di

programmazione per database di valori di default globali o per utente.

File system and URL. NSFileManager fornisce un'interfaccia per le operazioni su file

come creazione, rinomina, cancellazione e spostamento. NSFileHandle permette

operazioni su file a basso livello (per esempio ricerca nei file). NSBundle ricerca risorse

memorizzate in bundle ed alcune di queste può caricarle dinamicamente, per esempio nib

file. E' possibile utilizzare NSURL e le classi relative per rappresentare, accedere e gestire

fonti URL di dati.

Multithreading, operations, e subtasks. NSThread aiuta nello sviluppo di programmi

multithread e varie classi offrono meccanismi per accedere al controllo delle risorse dei

thread concorrenti. NSOperation e NSOperationQueue realizzano operazioni multiple,

concorrenti e non concorrenti, in ordine di dipendenza e di priorità. Con NSTask, è

possibile creare un processo figlio che esegue compiti e monitorizza i progressi. É utile

ricordare che, nonostante NSThread sia l'interfaccia principale per creare thread nelle

applicazioni Cocoa, è possibile utilizzare anche thread Posix ogni qual volta lo si ritiene

utile.

Comunicazione interprocesso. Molte delle classi in questa categoria presentano vari

generi di porte di sistema, socket, e server name e generalmente sono implementate in IPC

di basso livello. NSPipe rappresenta una pipe BSD, un canale di comunicazione

unidirezionale tra processi. E' importante sottolineare che le classi dei name server non

sono presenti nella versione Foundation di iPhone OS.

Networking. Le classi NSNetService e NSNetServiceBrowser forniscono l'architettura

Zeroconf chiamata Bonjour, è un potente sistema di pubblicazione e ricerca di servizi su

rete IP.

Notifications. Racchiude le classi sintetizzate in “Foundation: paradigmi e politiche”

3.3.1.1.

Page 66: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

66

Archiving e serialization. Le classi di questa categoria rendono possibile la persistenza

degli oggetti distribuiti. NSCoder e le sue sottoclassi, insieme al protocollo NSCoding

rappresenta i dati contenuti in un oggetto in un'architettura indipendente in modo da

permettere la registrazione di classe delle informazioni insieme ai dati. NSKeyedArchiver

e NSKeyedUnarchiver offre metodi per codificare oggetti, valori scalari, e decodificarli in

modo indipendente dall'ordine di codifica dei messaggi.

Servizi per linguaggi Objective-C. NSException e NSAssertionHandler forniscono una

soluzione orientata agli oggetti di manipolare asserzioni ed eccezioni nel codice. Un

oggetto NSInvocation è una rappresentazione statica di un messaggio Objective-C che il

programma può registrare ed invocare successivamente in un altro oggetto, è usato da

NSUndoManager e da Distributed Objects system. un oggetto NSMethodSignature

registra le informazioni dei tipi di un metodo e le usa nello scambio di messaggi.

NSClassDescription è una classe astratta per definire e ricercare le relazioni e le proprietà

di una classe.

3.3.2 Application Kit (Mac OS X)

Application Kit è un framework che contiene tutti gli oggetti necessari

all'implementazione della grafica, e delle combinazioni di eventi dell'interfaccia grafica:

finestre, pulsanti, menu, scroller, campi di testo e così via. Application Kit gestisce

efficacemente tutti i dettagli a schermo, comunicando con le periferiche e ripulendo le aree

dello schermo prima di visualizzare clip e immagini. Il numero delle classi di Application

Kit è elevato ma nella realtà molte di queste sono richiamate indirettamente, è possibile

comunque scegliere a che livello di profondità accedere ad Application kit:

• Attraverso Interface Builder è possibile creare connessioni tra gli oggetti

dell'interfaccia utente e gli oggetti controllati dall'applicazione. Le connessioni mettono

in relazione gli oggetti gestiti dall'utente attraverso l'interfaccia e coordinati dalla

struttura dati interna. Per esempio si potrebbe dover implementare un metodo da

Page 67: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

67

invocare quando l'utente sceglie una voce di menu.

• Controllare direttamente l'interfaccia utente, necessita una discreta familiarità con classi

e protocolli di Application Kit, per esempio permettere all'utente il drag and drop di

un'icona da una finestra all'altra richiede molta programmazione e familiarità con il

protocollo NSDragging.

• Implementare gli oggetti in maniera personalizzata attraverso il subclassing di NSView

o di altre classi, è possibile così scrivere metodi personalizzati di disegno usando

funzioni grafiche. Le sottoclassi richiedono una conoscenza approfondita di come

funziona Application Kit.

3.3.2.1 Descrizione di Application Kit

Application Kit comprende più di 125 classi e protocolli. Tutte le classi derivano dalla

classe NSObject del framework Foundation. Il diagramma in Figura 12 descrive le

ereditarietà e relazioni delle classi di Application Kit.

Figura 13: Classi Application Kit

Page 68: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

68

Come si evince l'albero della gerarchia è molto vasto ma poco profondo, infatti la distanza

massima dalla radice è di cinque classi, ma la maggior parte dell'albero non ha tale

profondità.

Alla radice del ramo più grande di Application Kit c'è la classe NSResponder, che

definisce una catena di responder, un lista ordinata di oggetti che rispondono ad eventi

degli utenti. Quando un utente clicca sul pulsante del mouse e seleziona una chiave, un

evento è generato e passato alla catena di responder alla ricerca di un oggetto che può

relazionarsi all'evento. Ogni oggetto che genera eventi deriva dalla classe NSResponder.

Le classi fondamentali di Application Kit (NSApplication, NSWindow, and NSView)

hanno come radice NSResponder.

Il secondo ramo più grande di classi discende da NSCell. Bisogna notare che questo

gruppo di classi è pressappoco uno specchio delle classi che sono ereditate da NSControl,

che deriva da NSView. Per gli oggetti dell'interfaccia utente che rispondono alle azioni

degli utenti, Application Kit usa un'architettura che divide il lavoro in controllo degli

oggetti e celle di oggetti. Le classi NSControl, NSCell e le loro sottoclassi definiscono un

insieme comune di oggetti per interfacce utente (come bottoni, cursori e browser) che

l'utente può utilizzare per manipolare determinate funzionalità dell'applicazione. Molti

controlli di oggetti sono associati con una o più celle di oggetti che implementano dettagli

grafici e gestione di eventi. Per esempio, un pulsante è costituito da un oggetto NSButton

ed un oggetto NSButtonCell.

Controlli e celle implementano meccanismi che si basano su importanti pattern di

Application Kit: i meccanismi target-action. Una cella può memorizzare un'informazione

che identifica il messaggio che potrebbe essere inviato ad un oggetto particolare quando

l'utente clicca (o con altri tipi di interazione) la cella stessa. Quando un utente utilizza un

controllo, ad esempio cliccando con il puntatore del mouse, il controllo estrae

l'informazione richiesta dalla cella ed invia un messaggio all'oggetto target. Target-action

restituisce senso all'azione dell'utente specificando l'oggetto di destinazione ed il metodo

Page 69: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

69

che dovrebbe invocare. Tipicamente si usa Interface Builder per settare target ed azioni

attraverso controlli a trascinamento da oggetti control verso l'applicazione o verso altri

oggetti, comunque è possibile settare target ed azioni anche attraverso la programmazione.

Un altro importante modello di design è attraverso il meccanismo di delega. Molti oggetti

in un'interfaccia d'utente, come campi testo e viste tabellari, definiscono una delega. La

delega è un oggetto che agisce in conto, oppure in coordinazione, dell'oggetto che lo ha

delegato, è quindi in grado di impartire specifiche delle applicazioni per la logica di

funzionamento dell'interfaccia utente.

Una caratteristica generale di Mac OS X 10.5 e sistemi successivi è l'indipendenza dalla

risoluzione: La risoluzione del monitor è disaccoppiato dal disegno fatto nel codice. Il

sistema automaticamente lavora il contenuto per il rendering a schermo. Le classi

Application Kit supportano risoluzioni indipendenti dagli oggetti dell'interfaccia utente.

3.3.2.2 Classi generali per le interfacce utenti

Le seguenti classi sono a disposizione per le interfacce utenti:

• Oggetto global application. Ogni applicazione usa una istanza di NSApplication che

controlla l'evento principale, tiene traccia delle finestre e menu dell'applicazione,

distribuisce gli eventi agli oggetti appropriati (essa stessa o una delle sue finestre),

riceve notifiche di eventi al livello di applicazione. Un oggetto NSApplication ha un

delegato notificato quando un'applicazione si avvia o termina, è nascosta o attivata,

potrebbe aprire un file selezionato dall'utente e così via. Con l'impostazione del

delegato dell'oggetto di NSApplication ed implementando i metodi del delegato, è

possibile personalizzare le azioni dell'applicazione.

• Finestre e view. Le classi di finestre e view, NSWindow e NSView, discendono da

NSResponder, così sono destinate a rispondere delle azioni dell'utente. Un oggetto

NSApplication contiene una lista di oggetti NSWindow per ogni finestra aperta

dell'applicazione ed ogni oggetto NSWindow mantiene una gerarchia di oggetti

Page 70: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

70

NSView. La gerarchia di view è usata per disegnare e manipolare eventi all'interno di

una finestra. Un oggetto NSWindow si occupa di eventi a livello di finestra, distribuisce

eventi nelle proprie view e fornisce aree di disegno per le proprie view. Un oggetto

NSWindow ha anche un delegato che permette di personalizzare il comportamento. A

Partire dalla versione 10.5 di Mac OS X le classi delle finestre e delle view di

Application Kit supportano caratteristiche potenziate di animazioni.

• NSView è la superclasse per tutti gli oggetti di una finestra. Tutte le sottoclassi che

implementano disegni usano metodi grafici; drawRect: è il metodo principale che viene

sovrascritto quando si crea un nuovo oggetto NSView.

• Classi Controller per Cocoa bindings. La classe astratta NSController e le sue

sottoclassi NSObjectController, NSArrayController, NSDictionaryController, e

NSTreeController sono parti dell'implementazione di Cocoa bindings. Questa

tecnologia sincronizza automaticamente i dati dell'applicazione registrati negli oggetti e

la presentazione dei dati nell'interfaccia utente.

• Panels (dialogs). La classe NSPanel è una sottoclasse di NSWindow che visualizza

informazioni transitorie, globali o urgenti. Per esempio è possibile usare un'istanza di

NSPanel, piuttosto che una istanza di NSWindow, per visualizzare messaggi di errori.

Application Kit implementa alcune funzioni comuni riferite ai documenti come Save,

Open, Print.

• Menus e cursori. Le classi NSMenu, NSMenuItem, and NSCursor definiscono

l'estetica ed il funzionamento di un menu e dei cursori che l'applicazione offre

all'utente.

• Raggruppamento e scorrimento delle view. Le classi NSBox, NSScrollView, e

NSSplitView forniscono “accessori” grafici per visualizzare oggetti view o collection di

view nelle finestre. Con la classe NSBox è possibile raggruppare elementi in finestre e

disegnare un confine intorno all'intero gruppo. La classe NSSplitView aggiunge view

verticali ed orizzontali, attribuendo ad ognuna di esse una parte di territorio comune,

Page 71: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

71

attraverso controlli, l'utente ridistribuisce il territorio alle view. La classe NSScrollView

e le sue classi d'aiuto, NSXlipView, fornisce un meccanismo di scrolling, nonché

oggetti grafici che permettono all'utente di controllare tali meccanismi. La classe

NSRulerView permette di aggiungere un righello e dei marcatori alle scroll view.

• Table view e outline view. La classe NSTableView fornisce dati in colonne e righe,

ideale anche per visualizzare tabelle di database, dove le righe sono i records e le

colonne sono gli attributi. L'utente può editare celle individuali e riadattare le colonne.

Impostando il delegato e l'oggetto origine dei dati è possibile controllare il

funzionamento ed il contenuto di un oggetto NSTableView. Outline view (per esempio

NSOutlineView o una sottoclasse di NSTableView) offre un altro approccio nella

visualizzazione tabulare dei dati. Con la classe NSBrowser è possibile creare un

oggetto con il quale gli utenti possono navigare e visualizzare i dati gerarchici.

3.3.2.3 Testo e caratteri

Il testo del sistema Cocoa è basato sul framework Core Text introdotto in Mac OS X 10.5.

Core Text fornisce una tecnologia, moderna, di basso livello ed alte prestazioni per la

stesura di testo. Utilizzando comunque il sistema Cocoa non è necessario accedere

direttamente a Core Text.

La classe NSTextField implementa un semplice input di testo in campo editabile, la classe

NSTextView invece prevede funzioni di editing più complesse per testi più estesi.

NSTextView, una sotto classe della classe astratta NSText, definisce l'interfaccia del

sistema esteso di testo. NSTextView supporta il testo esteso, allegati (grafica, file ed altro),

gestione degli input, key binding ed attributi del testo. Inoltre NSTextView lavora con

Font window e Font menu, stili di paragrafi, ordinamenti, appunti e permette la

personalizzazione e la delega, per tutto ciò è raro utilizzare sottoclassi di NSTextView.

Difficilmente è necessario creare istanze di NSTextView, considerando che nelle tavolozze

di Interface Builder come NSTextField, NSForm e NSScrollView contengono già oggetti

Page 72: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

72

NSTextView.

E' possibile anche fare manipolazioni più potenti e creative del testo, come visualizzarlo in

un cerchio, utilizzando NSTextStorage, NSLayoutManager, NSTextContainer e le classi

relazionate. Il sistema di testo Cocoa supporta inoltre liste, tabelle e selezioni non

contigue.

Le classi NSFont e NSFontManager incapsulano e gestiscono le famiglie di font,

dimensioni e varianti. La classe NSFont definisce oggetti per ogni singolo Font; per

efficienza questi oggetti, che possono rappresentare parecchi dati, sono condivisi da tutti

gli oggetti delle applicazioni. La classe NSFontPanel definisce altresì i la finestra dei font

che viene presentata all'utente.

3.3.2.4 Grafica e colori

Le classi NSImage e NSImageRep includono i dati grafici, aiutando e migliorando

l'accesso alle immagini registrate in file ed alla visualizzazione a video delle stesse. Ogni

sotto classe di NSImageRep include tecniche per disegnare le immagini da particolari tipi

di dati origine. La classe NSImage invece fornisce rappresentazioni multiple della stessa

immagine e prevede anche comportamenti come il caching. Le funzionalità di disegno e

delle immagini di Cocoa sono integrate nel framework Core Image.

Il colore è supportato dalle classi NSColor, NSColorSpace, NSColorPanel, NSColorList,

NSColorPicker, e NSColorWell. NSColor e NSColorSpace supportano una notevole

quantità di formati e rappresentazioni di colori, tra cui quelle personalizzate. Le altre classi

sono per la maggior parte classi di interfaccia: definiscono e presentano all'utente pannelli

e view che permettono di selezionare ed applicare colori, per esempio, l'utente può

trascinare un colore dalla finestra Color.

Le classi NSGraphicsContext, NSBezierPath, e NSAffineTransform aiutano con il disegno

vettoriale e per il supporto grafico come trasformazioni di scala, rotazioni e traslazioni.

Page 73: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

73

3.3.2.5 Stampe e Fax

Le classi The NSPrinter, NSPrintPanel, NSPageLayout, e NSPrintInfo lavorano insieme

per fornire i mezzi per stampare o inviare per fax le informazioni che l'applicazione

visualizza nella sua finestre e nelle view, è anche possibile creare un file PDF di un

NSView.

3.3.2.6 Documenti e supporto al File-System

La classe NSFileWrapper serve a creare oggetti che corrispondono a file e directory nel

disco, registra inoltre il contenuto del file nella memoria in modo da renderlo disponibile

alla visualizzazione, alla modifica o passaggio ad un'altra applicazione, prevede anche

un'icona per il trascinamento del file o di una sua rappresentazione come un allegato. E'

anche possibile utilizzare questa classe in foundation per accedere ed elencare il contenuto

di file e directory. Le classi NSOpenPanel e NSSavePanel a fornire interfacce utente

comode per il file system.

Le classi NSDocumentController, NSDocument, e NSWindowController definiscono

un'architettura per creare applicazioni basate su documenti. Tali applicazioni gestiscono

facilmente capacità di salvataggio, ritorno, chiusura e gestione dei documenti.

3.3.2.7 Internazionalizzazione e Character Input Support

Se un'applicazione deve essere usata in più parti del mondo deve poter essere

personalizzata, o localizzata per lingua, paese, o regione culturale, per esempio

un'applicazione potrebbe aver bisogno di stringhe di caratteri, icone, contenuto dell'help e

nib file in versioni differenti per le varie lingue. File di risorse specifiche per particolari

linguaggi sono raggruppati in una sottodirectory di un bundle (la directory con estensione

.lproj), di solito si imposta la localizzazione delle risorse di file tramite Interface Builder.

Le classi NSInputServer e NSInputManager, insieme al protocollo NSTextInput, danno

accesso alle applicazioni al sistema di gestione dell'input. Tale sistema interpreta le battute

da tastiera di diverse tastiere internazionali e genera i caratteri appropriati o eventi per

Page 74: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

74

visualizzare oggetti testo.

3.3.2.8 Operating-System Services

Application Kit fornisce servizi del sistema operativo di supporto alle applicazioni,

attraverso le seguenti classi:

• Condivisione dei dati con altre applicazioni. la classe NSPasteboard definisce il

pasteboard, un repository per i dati copiati dall'applicazione, rendendo questi dati a

disposizione di qualsiasi applicazione che deve utilizzarli. NSPasteboard implementa le

proprietà taglia-copia-incolla.

• Trascinamento. Attraverso poche righe di codice è possibile rendere gli oggetti

trascinabili e conformi ai protocolli NSDragging, NSDraggingDestination. Application

Kit nasconde tutti i dettagli di monitoraggio del cursore e dell'immagine trascinata.

• Controllo ortografico. La classe NSSpellServer consente di definire il servizio di

controllo ortografico e fornisce questo servizio alle altre applicazioni. per collegare

quindi all'applicazione il controllo ortografico bisogna usare la classe NSSpellChecker.

I protocolli SIgnoreMisspelledWords e NSChangeSpelling supportano meccanismi di

controllo ortografico.

3.3.2.9 Interface Builder Support

La classe astratta NSNibConnector e le sue sottoclassi, NSNibControlConnector e

NSNibOutletConnector rappresentano le connessioni in Interface Builder,

NSNibControlConnector gestisce un collegamento in Interface Builder e

NSNibOutletConnector gestisce una richiesta di connessione.

3.3.3 UIKit (iPhone OS)

Il framework, UIKit in iPhone OS è il framework gemello di Application Kit in Mac OS

X. Sono essenzialmente uguali: fornisce tutte le classi che un'applicazione necessita per

costruire e gestire le interfacce. Comunque bisogna sottolineare che ci sono delle

differenze su come vengono realizzati questi obiettivi.

Page 75: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

75

Una delle principali differenze è che, in iPhone OS, gli oggetti che appaiono sulla

interfaccia delle applicazioni Cocoa hanno caratteristiche e funzionamenti diversi rispetto

alle applicazioni Cocoa eseguite su Mac OS X, alcuni esempi tipici sono view del testo,

tabelle, e pulsanti, in più i modelli per la manipolazione delle immagini e dei testi sono

significativamente differenti nelle due piattaforme.

Le sezioni che seguono espliciteranno le differenze. E' possibile aggiungere oggetti UIKit

all'interfaccia di utente dell'applicazione in tre modi diversi:

• Usare Interface Builder per sviluppare l'applicazione, con finestre drag and drop, view

ed altre librerie di oggetti.

• Creare, posizionare e configurare oggetti programmando in un framework.

• Implementare oggetti di interfaccia utente personalizzate attraverso sottoclassi di

UIView o classi che discendono da essa.

3.3.3.1 Descrizione delle classi di UIKit

Come per Application Kit, le classi di UIKit sono ereditate da NSObject, la figura 12

rappresenta le relazioni e le gerarchie delle classi di UIKit. Così come Application Kit,

anche UIKit ha la classe Responder come radice del ramo principale. UIResponder

definisce anche le interfacce ed i comportamenti di default per metodi event-handling e

per le catene di responder, i quali sono una catena di oggetti, potenziali gestori di eventi.

Quando un utente scorre una view di una tabella con un dito o clicca su di un carattere in

una tastiera virtuale, UIKit genera un evento che passato alla catena di responder fino ad

un risponditore automatico dell'oggetto che lo gestisce.

Tutti i corrispondenti oggetti fondamentali, UIApplication, UIWindow, UIView

direttamente o indirettamente derivano da UIResponder.

Differentemente da Application Kit, UIKit non usa celle. I controlli, che sono gli oggetti

ereditati da UIControl, non richiedono celle per svolgere il loro ruolo primario: inviare

messaggi di azioni ad oggetti. Eppure il sistema con cui UIKit implementa il meccanismo

Page 76: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

76

di “azione” è diverso dal modello di Application Kit. La classe UIControl definisce un

gruppo di tipi di eventi per il controllo, per esempio un pulsante (UIButton) che invia un

messaggio di azione ad un oggetto target, è possibile invocare un metodo per associare

l'azione e la destinazione con uno o più tipologie di controllo degli eventi. Quando uno di

questi eventi si verifica, il controllo invia il messaggio d'azione.

Il framework UIKit fa largo uso della delega, tuttavia, l'attuazione della delega è diversa

rispetto ad Application Kit. Invece di usare protocolli informali, UIKit utilizza protocolli

formali, eventualmente con alcuni metodi definiti “opzionale”.

3.3.3.2 Application Coordination

Tutte le applicazioni eseguite su iPhone OS sono gestite da una singola applicazione

oggetto, che ha un ruolo molto simile a quello dell'oggetto NSApplication. un oggetto

UIApplication controlla il principale evento loop, tiene traccia delle finestre e view delle

applicazioni, e distribuisce gli eventi in arrivo agli appropriati oggetti risponditori.

L'oggetto UIApplication riceve anche le notifiche al livello di sistema ed eventi al livello

delle applicazioni. Molte di queste sono passate al suo delegato, che consente di iniettare

alle applicazioni specifici comportamenti quando l'applicazione si avvia o si chiude e

rispondere ai warning.

3.3.3.3 Differenze di modelli nei disegni e negli eventi

In Mac OS X, il mouse e la tastiera generano diversi eventi utente, Application Kit utilizza

oggetti NSEvent per incapsulare questi eventi. Su iPhone OS, tuttavia, i movimenti del

dito sullo schermo sono la causa di eventi, UIKit rappresenta tali eventi con la classe

UIEvent. Il contatto del dito però ha diversi scopi, per esempio il click del mouse oppure

due o più tocchi che si verificano nel corso di un intervallo temporale potrebbero essere un

“pizzico”. Così un oggetto UIEvent contiene uno o più oggetti che rappresentano il tocco

di un dito (UITouch). Il modello per la distribuzione e dispacciamento di eventi agli

oggetti che possono gestirli è quasi identico sulle due piattaforme, tuttavia, per gestire un

Page 77: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

77

evento, un oggetto deve prendere in considerazione la sequenza di tocchi per quello

specifico evento.

I modelli di disegno sono molto simili per Application Kit e UIKit. In UIKit, tuttavia, un

oggetto UIView ha uno strato di animazione ad esso associato per consentire l'animazione

dei cambiamenti all'interno delle view e nelle transizioni tra diverse view. Detto questo, il

livello di sviluppo di codice che prevede UIKit per il disegno è limitato. Pertanto, per

disegni articolati, un'applicazione deve utilizzare Core Graphics oppure OpenGLES.

3.3.3.4 Classi generali dell'interfaccia utente

Gli oggetti dell'interfaccia utente in iPhone OS sono visibilmente diversi da quelli

dell'interfaccia di Mac OS X. Tali differenze sono dovute ad uno schermo più piccolo ed

all'uso delle dita in luogo del mouse e della tastiera come input dell'utente. Gli oggetti

quindi dell'interfaccia iPhone devono essere sostanzialmente più grandi (per permettere

l'uso del touch) allo stesso tempo però bisogna ottimizzare lo spazio usando lo schermo

nel modo più esteso possibile.

Questi oggetti sono a volte diversi dagli oggetti analoghi in Mac OS X perchè devono

basarsi su concetti visivi ma anche tattili, per esempio consideriamo un oggetto picker per

le date, istanziato da una classe definita sia in Application Kit che in UIKit. In Mac OS Xil

picker avrà questo aspetto:

L'interfaccia del picker ha delle piccole aree per l'incremento dei componenti date, quindi

adatto al puntatore del mouse, ma contrasta con le necessità di iPhone che quindi avrà

questo tipo di interfaccia:

Page 78: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

78

Questo picker, infatti, è molto più comodo per input ricevuti da touch. Gli utenti possono

scorrere giorno, mese ed anno per selezionare agevolmente quello giusto.

Anche in UIKit molte classi si possono riassumere in gruppi funzionali:

• Controlli. Gli oggetti instanziati delle sottoclassi di UIControl consentono agli utenti di

inviare input alle applicazioni Oltre agli oggetti standard (UIButton) ed agli oggetti a

scorrimento (UISlider) ci sono controlli che simulano switch off/on (UISwitch),

controlli a ruote girevoli per la selezione di gruppi multidimensionali di valori

(UIPickerView), un controllo attraverso il paging dei documenti (UIPageControl) ed

altri controlli.

• Modal views. Le due classi ereditate da UIModalView servono per la visualizzazione

di messaggi all'utente sia sotto forma di fogli allegati, speciali view o finestre

(UIActionSheet) o come messaggi di alert (UIAlertView).

• Scroll views. La classe UIScrollView abilita le istanze delle sue sottoclassi a rispondere

al touch per scrolling all'interno di view più grandi. Quando un utente interagisce con

uno scroll, visualizza uno scorrimento degli indicatori di posizione nella view del

documento. Le sottoclassi di UIScrollView implementano view di tabelle, testo e web.

• Toolbars, barre di navigazione, e controller view. La classe UIViewController è la

classe base per la manipolazione di view. Un controller di view fornisce metodi per

creare, ruotare, osservare e manipolare view e risponde ai warning della memoria.

UIKit include sottoclassi di UIViewController per gestire toolbar, barre di navigazione

e picker.

Le applicazioni utilizzano sia le toolbar che le barre di navigazione per gestire il

Page 79: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

79

comportamento legato alla view principale dello schermo, in genere le toolbar sono

posizionate al di sotto della view e le barre di navigazione sopra. Gli oggetti toolbar,

UIToolbar, vengono utilizzati per passare tra modelli di view di un'applicazione, è

possibile usarli per visualizzare un set di funzioni che migliorano alcune azioni relazionate

alla view principale. Le barre di navigazione, UINavigationBar, gestiscono sequenze di

finestre o view in un'applicazione e per scorrere una gerarchia di oggetti definiti da

un'applicazione, per esempio, in Mail si usano le barre di navigazione per scorrere tra le

cartelle dell'account di posta o trai messaggi. È da notare come questo approccio differente

tra toolbar e barre di navigazione sia utile per mantenere coerenza nell'utilizzo di differenti

applicazioni.

3.3.3.5 Testo ed immagini

Gli utenti possono inviare testo alle applicazioni iPhone attraverso view di testo

(UITextView) oppure attraverso campi di testo editabili (UITextField). Queste classi

adottano il protocollo UIInputTraits per specificare l'aspetto e le funzionalità di una

tastiera virtuale che si presenta all'utente quando tocca un oggetto di input testo, ogni

sottoclasse che abilita un input di testo dovrebbe essere conforme a questo protocollo. Le

applicazioni possono visualizzare testo usando metodi UIStringDrawing, una categoria

della classe NSString. Inoltre, con la classe UIFont è possibile specificare le caratteristiche

dei font del testo in tutti gli oggetti che visualizzano testo, incluso celle di tabelle, barre di

navigazione ed etichette. UIKit utilizza oggetti UIImage per rappresentare ed incapsulare

immagini.

3.3.4 Comparazione tra classi di Application Kit e UIKit

Application Kit e UIKit sono framework per applicazioni Cocoa destinati a differenti

piattaforme: Mac OS X e iPhone OS. Considerando le affinità tra le piattaforme è

comprensibile che molte classi hanno nomi simili nei due framework, in molti casi il

prefisso, che cambia da NS a UI, è l'unica differenza. In molti altri casi, invece, il nome

Page 80: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

80

simile delle classi indica che hanno molte funzionalità in comune, ma rimangono

comunque delle differenze che possono riguardare i propositi, le gerarchie o il design. In

generale, le classi UIKit hanno un numero minore di metodi che la loro controparte in

Application Kit, questo perchè le applicazioni iPhone sono eseguite da un ambiente più

ristretto.

La figura 13 visualizza le classi UIKit con le corrispondenti classi in Application Kit, in

tabella invece sono descritte le differenze tra le maggiori classi dei due framework.

Page 81: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

81

Figura 12: Comparazione tra classi Application Kit ed UIKit

Page 82: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

82

Classi Comparazione

NSApplication

UIApplication

Queste due classi sono molto simili nel loro ruolo principale.

Forniscono un singolo oggetto che stabilisce l'ambiente di

visualizzazione dell'applicazione e l'evento principale loop,

distribuisce gli eventi e notifica un delegato quando lo specifica un

evento dell'applicazione. Comunque NSApplication gestisce eventi

che in iPhone non sono abilitati, come sospensione, riattivazione ed

hiding.

NSResponder

UIResponder

Anche queste classi sono molto simili, sono classi astratte che

definiscono un'interfaccia per rispondere ad eventi e gestire le

catene di risponditori. La principale differenza è che in NSRsponder

i metodi per la manipolazione sono definiti per mouse e tastiera, in

UIResponder sono definite per modelli di eventi multitouch.

NSWindow

UIWindow

La classe UIWindow si trova in un posto differente nella gerarchia

rispetto a NSWindows, è una sottoclasse di UIView, dal momento

che le classi di Application Kit discendono direttamente da

NSResponder. UIWindows inoltre ha funzionalità molto più limitati

in un'applicazione rispetto a NSWindows e fornisce un'area per le

view, smista gli eventi nelle view e converte tra le finestre e le

coordinate view.

NSView

UIView

Queste classi sono molto simili sia negli scopi che nei loro set di

metodi base. Permettono di spostare e ridimensionare le view,

gestire le loro gerarchie, spostare il loro contenuto e convertirne le

coordinate. Tuttavia UIView permette agli oggetti di avere capacità

intrinseche di animazioni.

NSContro

UIControl

Entrambe le classi forniscono un meccanismo per oggetti come

pulsanti o cursori che, se manipolati, permette all'oggetto di

Page 83: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

83

controllo di inviare un messaggio di azione all'oggetto destinazione.

Le classi implementano questo meccanismo di obiettivo-azione in

differenti modi, in gran parte a causa della differenza tra i modelli di

evento.

NSViewController

UIViewController

Lo scopo di entrambe le classi è gestire le view, è diverso però il

modo in cui si ottiene. La gestione offerta da un oggetto

NSViewController dipende dal bindings che è una tecnologia

specifica di Mac OS X. Gli oggetti UIViewController sono usati nei

modelli delle applicazioni in iPhone OS per la navigazione

nell'interfaccia utente, ad esempio per il controllo della view

attraverso la barra di navigazione.

NSTableView

UITableView

NSTableView discende da NSControl, ma UITableView non

discende da UIControl, la differenza sostanziale è che gli oggetti

NSTableView supportano più colonne di dati, mentre gli oggetti

UITableView ne supportano una sola e quindi funziona più come

una lista che come una tabella di dati.

Anche tra le classi minori si possono trovare differenze, per esempio UIKit ha le classi

UITextField e UILabel per i campi di testo editabili e per quelli non editabili, quindi in

forma di etichette. Con la classe NSTextField è possibile creare entrambi i tipi di oggetti

semplicemente settando text-field come attributo. Similmente, la classe

NSProgressIndicator può creare oggetti che corrispondono alle istanze di

UIProgressIndicator e UIProgressBar.

3.4 Pubblicazione di Software

Per distribuire un'applicazione iPhone bisogna aver aderito al programma iPhone

Developer Program. L'adesione infatti prevede la possibilità di scaricare gratuitamente il

software necessario allo sviluppo e successivamente permette di accedere al App Store.

Nel seguito saranno descritti i vari tipi di adesione al programma di sviluppo applicazioni

Page 84: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

84

della Apple.

Per sviluppare e distribuire quindi un'applicazione per iPhone la Apple prevede le seguenti

fasi:

• Sviluppare il software con gli strumenti messi a disposizione da Apple e descritti nei

paragrafi precedenti.

• Testare il software prima su iPhone Simulator e successivamente sul dispositivo. Se

necessario è possibile ottimizzare le prestazioni del software sempre attraverso gli

strumenti offerti da Apple.

• Distribuire l'applicazione attraverso l'App Store, sia in maniera gratuita che a fini

commerciali.

3.4.1 iPhone Developer Program

Iphone Developer Program offre un processo completo ed integrato per lo sviluppo di

software, il debugging e la distribuzione di applicazioni per iPhone ed iPod Touch.

Esistono due tipi di accesso al programma di sviluppo per iPhone:

1. Standard Program per sviluppatori che voglio produrre applicazioni commerciali o

gratuite da distribuire sull'App Store. Tale programma ha il costo di 99 $.

2. Enterprise Program è invece rivolto alle aziende con più di 500 dipendenti che

vogliano sviluppare e distribuire al loro interno applicazioni per iPhone ed iPod Touch,

il suo costo è di 400$.

È da notare comunque l'esistenza di un altro programma di sviluppo, iPhone Developer

University Program, rivolto però esclusivamente agli istituti di istruzione superiore negli

Stati Uniti.

Il kit di sviluppo è scaricabile dal sito della Apple senza la necessità di sottoscrivere i

programmi a pagamento. Esiste infatti la possibilità di registrarsi gratuitamente per

scaricare L'SDK per iPhone semplicemente creando un account Apple id. Tale account

permette l'accesso alle sezioni iPhone Dev Center dove è possibile trovare tutta la

Page 85: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

85

documentazione messa a disposizione da Apple per lo sviluppo di software. Inoltre è

possibile accedere alla sezione Web Apps Dev Center, per lo sviluppo di siti ottimizzati

per iPhone.

Bisogna inoltre specificare che l'adesione gratuita al programma non permette di installare

sul proprio dispositivo le applicazioni sviluppate, neanche a scopo di test. Prima di poterlo

fare infatti è necessaria l'adesione ai programmi descritti precedentemente.

Il vincolo per l'installazione è la firma digitale apposta da Apple una volta visionato il

software, verificati eventuali procedure pericolose ed approvato il progetto. Solo dopo

infatti è possibile distribuirlo tramite App Store.

Page 86: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

86

Capitolo 4 Linguaggio di programmazione Objective-C Il capitolo che segue descrive le caratteristiche degli oggetti in Objective-C e quali

vantaggi portano nello sviluppo di software, inoltre sarà descritto come usare Objective-C

per inviare messaggi ad oggetti e come gestire i valori di ritorno. Il capitolo inizierà con

un piccolo esempio di codice per spiegare la struttura di un semplice programma, seguirà

poi con la descrizione delle funzionalità della classe root, NSObject, e spiegherà come

utilizzare la sua interfaccia di programmazione per creare oggetti, per fornire Introspection

e gestire i cicli di vita degli oggetti stessi.

4.1 Cenni storici Objective-C

Objective-C, è un linguaggio di programmazione orientato agli oggetti, sviluppato da Brad

Cox alla metà degli anni '80 presso la Stepstone Corporation. È possibile definire

Objective-C come un piccolo ma potente set di estensioni per lo standard ANSI C.

Objective-C è nato per restituire al C un approccio alla programmazione orientata ad

oggetti.

Le estensioni a oggetti con cui Objective-C arricchisce il modello semantico del C sono

ispirate al linguaggio Smalltalk, in particolar modo alla gestione dei messaggi. In

Objective-C sono presenti molti concetti innovativi oltre a supportare tutti gli elementi

classici della programmazione a oggetti e mantenere piena compatibilità con il linguaggio

C. La diffusione è stata legata al framework, predecessore di Cocoa, OpenStep di NeXT,

società fondata da Steve Jobs nel 1985.

Le caratteristiche del sistema runtime invece, collocano l'Objective-C tra i linguaggi ad

oggetti dinamici. Fornisce infatti supporto runtime per la distribuzione dei messaggi e

specifica convenzioni sintattiche per definire nuove classi, fornisce anche supporto per

diversi meccanismi presenti in altri linguaggi orientati agli oggetti come C++ e Java, come

gerarchie, incapsulamento, riusabilità e polimorfismo. Ciò nonostante, Objective-C è

diverso dagli altri linguaggi orientati agli oggetti, spesso in caratteristiche essenziali.

Page 87: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

87

Diversamente da C++ infatti non supporta il sovraccarico di operatori, template o

gerarchie multiple. Tali carenze, comunque sono ben bilanciate dai suoi punti di forza.

4.2 Programma di esempio “Hello, World!”

Per chiarire meglio la struttura del linguaggio si inizierà con un semplice programma da

linea di comando che mostra a video una scritta, “Hello, World!”. Si consideri prima il suo

codice ed in seguito si analizzeranno le sue parti:

Page 88: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

88

/* Commenti:

** Il codice che segue è un esempio di

**programma che restituisce a video la scritto “Hello World”

*/

#include <objc/Object.h>

@interface Greeter:Object

{

/* Tale spazio è lasciato vuoto, ma

** in generale in questa sezione

** vengono dichiarate istanze di variabili.

*/

}

- (void)greet;

@end

#include <stdio.h>

@implementation Greeter

- (void)greet

{

printf("Hello, World!\n");

}

@end

#include <stdlib.h>

int main(void)

{

id myGreeter;

myGreeter=[Greeter new];

[myGreeter greet];

[myGreeter free];

return EXIT_SUCCESS;

}

Riquadro 1: Hallo World

Page 89: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

89

Il comando per eseguire e visualizzare l'output del programma è indicato nel Riquadro 2. bash-2.05a$ ./hello

Hello, World!

Riquadro 2: Output

Per facilitare il lavoro del compilatore è necessario fare un corretto uso delle estensioni dei

file, la seguente tabella indica le estensioni di Objective-C, C e C++ e le corrispondenti

direttive per GCC.

Linguaggi Estensioni Direttive

C .c -x c

Objective-

C

.m -x objective-c

C++ .c o .c++ -x c++

Tabella 1: Estensioni dei file

Ogni programma è formato da funzioni e variabili, le funzioni descrivono cosa fa il

programma e le variabili contengono i dati che le funzioni elaborano. In linguaggi orientati

ad oggetti, le variabili e le funzioni fanno entrambe parte degli oggetti. Objective-C

gestisce la comunicazione tra gli oggetti attraverso lo scambio di messaggi, attraverso di

essi si invocano le funzioni o scambiano parametri.

Un oggetto consiste in una variabile istanziata (dato) che rappresenta lo stato di un

oggetto, e metodi (funzioni) che agiscono sulle variabili in risposta a messaggi. Un

oggetto quindi può essere visto come un semplice programma da chiamare (inviandogli un

messaggio) per eseguire una semplice azione.

Molto spesso si utilizzano oggetti già descritti in altri file, per inserirli nel programma da

implementare si utilizza la direttiva #include, indicando così al compilatore di andare a

prelevare l'oggetto segnalato. Nell'esempio si è incluso l'oggetto Object.h, fornito dal

Page 90: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

90

compilatore.

Gli oggetti definiti in Object.h sono la base di tutti gli oggetti, per questo motivo si

considera Object come la classe radice di tutte le classi.

4.2.1 Oggetti, Classi, metodi ed Istanze

Un programma orientato ad oggetti è generalmente costituito da una diversità di oggetti

che interagiscono tra loro. In Objective-C si dichiara un oggetto definendo la sua classe.

La definizione della classe quindi è il prototipo per un determinato tipo di oggetto,

dichiara infatti le variabili di istanza che fanno parte di ogni membro della classe e

definisce un set di metodi che tutti gli oggetti della classe possono usare. Il compilatore

crea un solo oggetto accessibile per ogni classe, detto class object. Tale oggetto ha il

compito di generare nuovi oggetti appartenenti alla classe. In sostanza class object è la

versione compilata della classe, gli oggetti che crea sono le istanze della classe. Gli oggetti

del programma sono le istanze create dal class object al tempo di esecuzione. Inoltre è

importante notare come gli oggetti creati da una classe ereditino tutti i metodi delle

superclassi della classe da cui derivano.

La dichiarazione delle interfacce di classe avviene attraverso la struttura

@interface/@end, tale sezione normalmente è salvata in un file con estensione .h, anche

se nell'esempio del Riquadro 1, per motivi di semplicità, è stato inserito nel file principale.

Nel seguente riquadro è indicato lo stralcio di codice dell'esempio incluso nella struttura

@interface/@end.

Page 91: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

91

@interface Greeter:Object

{

//è la sezione destinata alla dichiarazione

//delle veriabili istanziate

}

- (void)greet;

@end

Riquadro 3: Struttura @interface/@end

La prima linea indica al compilatore che Greeter è una sottoclasse di Object, ereditandone

così i metodi e posizionando la nuova classe nella gerarchia delle classi. In tal modo un

oggetto Greeter ha le stesse funzionalità di un oggetto Object. All'interno delle parentesi

graffe invece vengono dichiarate le variabili di istanza, quindi la struttura dati di ogni

istanza della classe.

Dopo le parentesi graffe e prima della direttiva @end vengono dichiarati i metodi pubblici

associati alla classe. In tal modo con la dichiarazione “- (void)greet;”, Greeter può godere

anche del nuovo metodo greet. I metodi sono funzionalità che una classe può offrire e ne

esistono di due tipi: quelli ereditati dalle classi da cui discende e quelli aggiunti. Tra i

metodi aggiunti va notato che sono pubblici tutti quelli richiamati nell'interfaccia della

classe a cui appartengono (file con estensione .h); sono invece privati quei metodi

implementati direttamente nella descrizione della classe (file con estensione .m). Un

metodo che può essere usato da una istanza della classe viene preceduto dal segno “-”, un

metodo di questo tipo quindi può essere usato solo in presenza di una istanza. Un metodo

che invece viene usato indipendentemente dalle istanze dalla classe viene preceduto dal

segno “+” e chiamato “metodo di classe”.

All'interno delle parentesi tonde che precedono il nome del metodo è definito il tipo

restituito dal metodo stesso. Nel caso in cui non venga specificato si considera restituito

un tipo generico id. Gli argomenti del metodo invece vengono dichiarati dopo i due punti,

Page 92: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

92

come nel seguente esempio:

- (void)greet:(float)agreat;

così facendo il metodo greet ha come argomento agreat di tipo float. Se gli argomenti

sono molteplici invece, questi vengono aggiunti in sequenza come nel seguente esempio:

- (void)greet:(float)agreat minus(int)aminus;

la definizione dell'interfaccia di una classe viene conclusa con la direttiva @end.

È possibile inoltre estendere le funzionalità delle classi, tali estensioni sono infatti come

categorie anonime. I metodi che dichiarano però devono essere implementati nel blocco

@implementation del main per la classe corrispondente. È utile notare che il compilatore

non può verificare che tutti i metodi siano stati implementati.

4.2.2 Ereditarietà

Dall'esempio è intuibile quanto sia importante la funzionalità di ereditarietà di Objective-

C, in quanto con una sola riga di codice abbiamo incluso nella nostra classe tutti i metodi e

dati presi dalla classe Object. Questo però non rende personalizzata la classe Greeter, in

quanto è identica alla classe Object, Quello che la differenzia invece è l'aggiunta del

metodo greet attraverso la procedura - (void) greet, con la quale si è indicato al

compilatore l'aggiunta di un metodo greet associata ad ogni oggetto Greeter. È possibile

quindi considerare le definizioni di classe come additive, in quanto dichiarare una classe

significa aggiungere metodi alla classe da cui deriva.

4.2.3 Implementazione

Successivamente alla definizione delle classi si passa alla fase di implementazione in cui

si descrive cosa l'oggetto Greeter deve fare. Poiché si sono fatti ereditare al nostro oggetto

tutti i metodi della classe Object, non si deve implementare nulla se non quelle funzioni

che personalizzano l'oggetto greeter.

Page 93: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

93

#include <stdio.h>

@implementation Greeter

- (void)greet

{

printf("Hello, World!\n");

}

@end

Riquadro 4: Implementazione 1

La sezione indicata in Riquadro 4 indica cosa il programma deve fare, in particolare deve

visualizzare a video le parole Hello, World!.

La prima notazione da fare nel Riquadro 4 è la presenza di un'altra direttiva #include.

Generalmente infatti le direttive #include vengono tutte raggruppate all'inizio del

programma, ma in questo caso è inclusa nella sua sezione di riferimento, in modo da

semplificare la spiegazione.

In conclusione bisogna considerare la sezione che definisce cosa il programma deve fare.

Ogni programma ha una funzione speciale detta main. In genere è possibile chiamare in

qualunque modo le funzioni implementate, l'importante è non chiamarle main, attraverso

tale funzione infatti si indica al compilatore il punto di accesso al codice eseguibile.

Si analizzi quindi la funzione main descritta nel Riquadro 5:

Page 94: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

94

#include <stdlib.h>

int main(void)

{

id myGreeter;

myGreeter=[Greeter new];

[myGreeter greet];

[myGreeter free];

return EXIT_SUCCESS;

}

Riquadro 5: Funzione main

Notazione importante è l'uso delle parentesi graffe, { e }, chiamate blocco delle

dichiarazioni. In genere ogni funzione ha un proprio blocco di dichiarazioni. Nell'esempio

indicato nel Riquadro 5 la funzione main ha 5 dichiarazioni che si concludono con il

simbolo “;”. Inoltre è possibile superare il limite delle singole dichiarazioni

raggruppandole, ma sempre all'interno delle parentesi graffe.

Innanzitutto viene dichiarata una variabile, (un oggetto) chiamata myGreeter.

id myGreeter;

Successivamente si crea l'oggetto della classe Greeter ed una nuova istanza inviando il

messaggio new a Greeter ed associandolo all'oggetto di tipo id14 myGreeter.

myGreeter = [Greeter new];

14 Nella dichiarazione viene utilizzato un tipo di variabile id, definito in Objective-C come un puntatore ad un oggetto

generico. L'utilizzo di un tipo id permette di non specificare al momento della dichiarazione il tipo di oggetto

myGreeter (vedi il paragrafo 4.3.2 Dinamicità in Objective-C).

Page 95: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

95

4.2.4 Messaggi e polimorfismo

Inviando un messaggio ad un oggetto è possibile indicare che metodo eseguire. Nell'esempio

considerato il messaggio indica all'oggetto Greeter di eseguire il metodo new, uno dei metodi

ereditati dalla classe Object.

Un'altro possibile modo di creare un oggetto è nel seguente modo:

myGreeter = [[Greeter alloc] init];

Tale metodo è spesso utilizzato nella programmazione Cocoa e GNUstep, è possibile

quindi inviare due messaggi nidificati ad un oggetto.

Ottenuto un oggetto funzionante, è possibile inviagli altri messaggi per implementare

metodi, nel caso dell'esempio il metodo greet.

Una volta che l'oggetto ha svolto il suo compito è necessario rilasciarlo (con il messaggio

release) in quanto con la sua creazione è stata occupata memoria che potrebbe servire per

la creazione di altri oggetti.

La funzione finisce quando ritorna un valore EXIT_SUCCESS che indica la corretta

chiusura della funzione.

Si osservino ora alcune caratteristiche che riguardano i messaggi scambiati. I messaggi in

Objective-C appaiono nella stessa posizione sintattica delle chiamate di funzioni in

standard C, ma poiché i metodi appartengono ad un oggetto, i messaggi si comportano in

maniera diversa rispetto alle funzioni. In particolare un oggetto può essere utilizzato

soltanto da alcuni metodi che gli sono stati associati, non è possibile quindi mischiare i

metodi tra oggetti anche se hanno lo stesso nome. Tale approccio permette ad oggetti

diversi di rispondere allo stesso messaggio in modo diverso, ad esempio un cerchio o un

rettangolo possono rispondere in maniera diversa ad istruzioni identiche. Questa

Page 96: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

96

caratteristiche, definita polimorfismo, svolge un ruolo significativo nella progettazione di

programmi Objective-C e sarà affrontata nella trattazione dei paragrafi successivi in tutte

le sue caratteristiche. Insieme alla caratteristica di dinamicità, in particolare il binding

dinamico (vedi paragrafo 4.3.2 Dinamicità in Objective-C) è possibile scrivere codice che

potrebbe essere applicato ad un numero qualsiasi di oggetti, senza dover scegliere al

momento dell'implementazione. È possibile infatti implementare un metodo che invia un

messaggio ad un oggetto id, potenzialmente quindi tutti gli oggetti possono ricevere tale

messaggio.

4.2.5 Scomporre il codice in più file

Objective-C, esattamente come il C, prevede la possibilità di strutturare un programma in

più file. È possibile quindi descrivere l'interfaccia delle classi in file con estensione “.h” e

successivamente implementarle in file con estensione “.m”.

Si noti che strutturare il programma in file che distinguono le diverse classi favorisce da

un lato la leggibilità del codice, dall'altro il riutilizzo di classi già implementate.

4.2.6 Elementi comuni al C

Come si è descritto in precedenza, Objective-C è un'estensione del linguaggio C, nel

seguito quindi si continuerà con la descrizione di quegli elementi C che compongono

oggetti e funzioni.

4.2.6.1 Tipi di dato

I “tipi” di dato indicano l'insieme dei valori che una variabile (o il risultato di

un'espressione) può assumere e le operazioni possibili su di essa. I linguaggi di

programmazione possono godere di tipizzazione dinamica o statica. La differenza risiede

nel fatto che in una tipizzazione statica una variabile non può cambiare il valore

memorizzato fino alla compilazione, deve quindi conservare un dato del tipo per cui la

variabile è stata inizializzata.

Page 97: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

97

Objective-C è un linguaggio che gode della tipizzazione dinamica15. La loro differenza è

nell'assegnazione dei valori dati alle variabili. Una variabile è infatti come un contenitore

di valori, per esempio scrivere VAR=1 significa che la variabile chiamata VAR avrà 1

come valore, questo tipo di assegnazione è dinamica in quanto non si era specificato che

VAR potesse contenere valori interi. In un linguaggio a tipizzazione dinamica quindi è

possibile assegnare VAR=a. È possibile quindi in Objective-C creare un oggetto e soltanto

al tempo di esecuzione assegnargli un valore di un determinato tipo. Una tale procedura

non genererebbe infatti errore al tempo di compilazione.

Il linguaggio C invece è staticamente tipizzato. Bisogna quindi dichiarare che tipo di dato

una variabile può rappresentare. Per fare questo C fornisce tipi di dati predefiniti con i

quali vengono inizializzate le variabili.

I “tipi” servono a dare al compilatore indicazioni sul tipo di dato da memorizzare e la

memoria che utilizzano per registrare tali informazioni. Tipo di

Dato Descrizione Dimensione

Char Un singolo carattere del set di caratteri locale 1 byte

Int Un numero intero (1, 4, 300) 4 byte

Float Un numero in virgola mobile (1.2, 4.78) 4 byte

Riquadro 6: Tipi standard in C

char. È l'unità base in un programma C oppure Objective-C, tutte le altre derivano dal

char. Rappresenta un singolo carattere come 'a' oppure '3', la sua dimensione è definita in

limitis.h.

15 Vedi paragrafo 4.3.2 Dinamicità in Objective-C.

Page 98: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

98

Tipo di Dato Descrizione Dimensione

Short Intero corto 2 byte

Long Un intero doppio corto 4 byte

Long long Un intero doppio lungo 8 byte

Double Float a doppia precisione 8 byte

Riquadro 7: Tipi derivati

Tutti i tipi menzionati sono comuni alle macchine a 32 bit, come Intel Pentium e sistemi

compatibili. La lunghezza delle variabili è dipendente dalla macchina ed è possibile

trovarla nei file limits.h e float.h.

Objective-C, inoltre, introduce i tipi di dato id, come introdotto nell'esempio “Hello

World” inizializzando un oggetto myGreeter. A tale oggetto successivamente si è associato

infatti una istanza della classe Greeter con tutti i suoi metodi.

4.2.6.2 Funzioni

Dopo aver analizzato i dati ed i tipi di dato bisogna valutare le routine base che li

manipolano, queste sono le funzioni. Tutti gli oggetti (in un linguaggio orientato ad

oggetti) consistono in dati e funzioni, che verranno descritte nel seguito.

Nel Riquadro 8 è indicata la struttura di una funzione in linguaggio C.

return-type function-name(parameter declaration, if any)

{

declarations;

asignments;

statements;

}

Riquadro 8: Funzione in C

Ogni funzione può essere chiamata in qualunque modo fuorchè main, perchè, come già

accennato, per il compilatore la funzione main ha il valore di funzione principale. Si

Page 99: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

99

considera inoltre che ogni funzione ha un valore di ritorno e può avere dei parametri. Alla

sua conclusione, una funzione deve restituire un parametro, ad esempio per indicare che

ha avuto una conclusione positiva potrebbe restituire uno zero. Il parametro restituito

potrebbe altresì essere una dichiarazione o qualunque altro tipo di dato analizzato

precedentemente.

Per i parametri dichiarati è possibile fare le stesse affermazioni. I parametri dichiarati

descrivono i dati che la funzione si aspetta. Nel caso dell'esempio 'Hallo, World!' la

funzione main è definita come void il che vuol dire che non si aspetta nessun input.

Nella funzione main quindi il tipo di ritorno dalla funzione è un int e non vi sono

dichiarazioni di parametro, ciò significa che la funzione non accetta alcun argomento, non

è possibile quindi inviare dati a questa funzione dal momento che si definisce void.

Il corpo della funzione è tra parentesi graffe { e }, che contengono quindi tutto ciò che

deve elaborare la funzione main.

Come è mostrato nell'esempio Hello, World! È intuibile quanto una funzione potrebbe

dipendere da una libreria esterna. In realtà molte funzioni dipendono da librerie esterne,

per questo infatti i linguaggi C ed Objective-C risultano molto compatti.

4.2.6.3 Costrutti

Objective-C prevede la possibilità di valutare se un oggetto è true o false, consentendo

così la possibilità di creare cicli while e for. Inoltre è previsto l'uso del costrutto if … else

e delle abbreviazioni dei valori incrementali come: Incrementi Abbreviazione

s=s+1; s++;

s=s-1; s--;

s=s+5; s+=5;

s=s*j; s*=j;

L'implementazione di cicli e costrutti è identica a quanto avviene nel linguaggio C.

Page 100: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

100

4.3 Objective-C e oggetti Cocoa

Nel paragrafo precedente si è studiato un semplice programma di esempio per descrivere

la struttura base del linguaggio Objective-C. In questo paragrafo invece si affronteranno le

caratteristiche principali di tale linguaggio e lo si osserverà in relazione agli oggetti Cocoa.

Come discusso precedentemente, Cocoa è strutturalmente orientato agli oggetti, dai suoi

paradigmi e meccanismi all'architettura event-driven. Nella trattazione seguente si farà

riferimento a SimpleCocoaTool (Riquadro 9) un programma di esempio da riga di

comando creato usando il framework Foundation per Mac OS X. Tale codice prende come

argomenti una serie arbitraria di parole, il programma rimuove le ripetizioni, le ordina e

restituisce in output la lista in ordine alfabetico delle stesse.

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSArray *args = [[NSProcessInfo processInfo] arguments];

NSCountedSet *cset = [[NSCountedSet alloc] initWithArray:args];

NSArray *sorted_args = [[cset allObjects]

sortedArrayUsingSelector:@selector(compare:)];

NSEnumerator *enm = [sorted_args objectEnumerator];

id word;

while (word = [enm nextObject]) {

printf("%s\n", [word UTF8String]);

}

[cset release];

[pool release];

return 0;

}

Riquadro 9: SimpleCocoaTool

Il primo fattore da notare è che il codice appare sintetico, forse molto più dello stesso

Page 101: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

101

codice scritto in una versione standard di ANSI C e nonostante l'apparenza bisogna dire

che molti degli elementi di questo codice sono simili a quelli ANSI C. Questi elementi

comprendono l'assegnazione degli operatori, il controllo del flusso di dichiarazioni

(while), le chiamate verso le routine delle libreria C (printf) e così via.

L'output di SimpleCocoaTool è:

localhost> SimpleCocoaTool a z c a l q m z

a

c

l

m

q

z

Riquadro 10: Output di SimpleCocoaTool

Molti esempi nei paragrafi seguenti ricalcano il codice appena esposto.

4.3.1 I vantaggi di Objective-C

Programmare una nuova procedura, con un approccio orientato agli oggetti, è facilitato

principalmente pensando ad un oggetto come una struttura con le funzioni ad esso

associate. Questo approccio non è molto lontano dalla realtà, in particolar modo in termini

di realizzazione runtime.

Page 102: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

102

Objective-C è un linguaggio estremamente improntato sullo scambio di messaggi,

caratteristica che restituisce un elevato dinamismo. Quando un oggetto viene creato, la

memoria viene allocata e le sue variabili di istanza inizializzate. Ogni oggetto così creato

nasconde una struttura dati il cui primo membro è il puntatore isa, molti dei membri

restanti sono definiti dalle classi e superclassi dell'oggetto. Il puntatore isa punta alla

classe dell'oggetto (vedi Figura 14) che possiede a sua volta un puntatore alla propria

superclasse ed una tabella di dispatch. Questa tabella contiene i selector che puntano alle

implementazioni dei metodi rappresentati dai selector stessi. Ad esempio il selector per il

metodo setOrigin:: è associato all'indirizzo della procedura che implementa setOrigin::.

Ogni classe quindi è legata attraverso un puntatore alla propria superclasse. Attraverso

questa catena di riferimenti, un oggetto ha accesso a tutti i metodi implementati dalla

propria classe e dalla superclasse. Il puntatore isa è fondamentale per il meccanismo di

distribuzione dei messaggi e per il dinamismo degli oggetti Cocoa.

Questa visione degli oggetti semplifica notevolmente cosa accade nel runtime Objective-C

per la distribuzione dei messaggi, le gerarchie ed altre caratteristiche generali di

comportamento degli oggetti. Inoltre questo tipo di approccio è fondamentale per

comprendere le principali caratteristiche di Objective-C ed il suo dinamismo.

4.3.2 Dinamicità di Objective-C

Objective-C è un linguaggio estremamente dinamico, in quanto sposta molta della

responsabilità di risoluzione simbolica dal tempo di compilazione a tempo di runtime,

Figura 13: Puntatore ISA

Page 103: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

103

quando il controllo è dell'utente. Objective-C è un linguaggio più dinamico di altri per il

possesso di tre caratteristiche principali: • Tipizzazione dinamica (Dynamic typing), determinando la classe di un oggetto a

runtime

• Invocazione dinamica (Dynamic binding) dei metodi, determinando il metodo da

invocare a runtime

• Caricamento dinamico (Dynamic loading), aggiungendo nuovi moduli ad un software

a runtime

Per la tipizzazione dinamica Objective-C introduce il tipo id, che può rappresentate ogni

tipo di oggetto.

Il tipo id rende possibile la sostituzione di ogni tipo di oggetto a runtime, pertanto è

possibile lasciare ad altri fattori in fase di esecuzione la scelta di quale tipo di oggetto

inserire nel codice. Tale tipizzazione permette associazioni tra gli oggetti da determinare in

fase di esecuzione, piuttosto che forzarli nel codice in una struttura statica. I tipi statici

garantiscono al tempo di compilazione una maggiore integrità dei dati, in cambio di questa

maggiore integrità la tipizzazione dinamica offre maggior flessibilità. Inoltre è possibile

verificare il tipo di oggetto a runtime, determinando la sua idoneità per particolari

operazioni, ovviamente è anche possibile definire gli oggetti staticamente.

La tipizzazione dinamica garantisce robustezza all'invocazione dinamica di metodi. La

seconda caratteristica di dinamicità in Objective-C rimanda così la decisione del metodo

da utilizzare al tempo di esecuzione. L'invocazione del metodo avviene quindi non al

tempo di compilazione ma proprio quando un messaggio è stato recapitato. Con queste

due caratteristiche di dinamicità è possibile quindi ottenere diversi risultati ogni volta che

eseguiamo il codice. Fattori al tempo di esecuzione possono in tal modo determinare sia il

ricevitore che il metodo da invocare.

Quando si invia un messaggio ad un oggetto tipizzato dinamicamente, il sistema runtime

usa il puntatore isa del ricevitore per determinare la classe dell'oggetto e da lì il metodo da

Page 104: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

104

invocare, il metodo così è legato dinamicamente al messaggio. Nel codice, inoltre, non

bisogna aggiungere nulla per beneficiare della dinamica dei metodi invocati, avviene tutto

in trasparenza nel momento in cui viene inviato un messaggio, maggiormente se l'oggetto

è tipizzato dinamicamente.

In fine, il caricamento dinamico, è la caratteristica Cocoa che dipende da Objective-C per

il supporto runtime. Grazie al caricamento dinamico un programma Cocoa può caricare

codice eseguibile e le risorse necessarie quando ne ha bisogno, senza doverlo fare al

momento del lancio. Il codice eseguibile (collegato prima del caricamento) spesso

contiene nuove classi che vengono integrate nell'immagine runtime del programma. Sia il

codice che le risorse localizzate (incluso il nib file) sono contenute in un bundle e sono

caricate esplicitamente da metodi definiti nella classe NSBundle di Foundation.

Questo tipo di caricamento di codice e risorse migliora le prestazioni diminuendo la

memoria richiesta dal sistema, conseguenza più significativa è che le applicazioni

diventano estensibili. Altra conseguenza è la possibilità di aggiungere un'architettura di

plug in alle applicazioni, permettendo così agli sviluppatori di personalizzare il software

con moduli aggiuntivi che l'applicazione può caricare molto tempo dopo il suo rilascio,

ammettendo però che il design sia coerente e che le classi non entrino in conflitto.

4.3.3 La Classe Root

Il linguaggio Objective-C ed il sistema runtime non sono sufficienti per costruire un

programma orientato agli oggetti, manca una definizione dell'interfaccia comune a tutti gli

oggetti; la classe root fornisce tale definizione.

Una classe root è chiamata così perchè è la radice di una gerarchia di classi, in questo caso

della classe gerarchica Cocoa. La classe root non deriva da nessuna classe e tutte le altre

classi derivano da essa. Gli oggetti Cocoa derivano gran parte delle loro funzionalità dalla

classe root, attraverso questa, Cocoa interagisce con il runtime.

Cocoa fornisce due classi di root, NSObject e NSProxy, quest'ultima classe è definita

Page 105: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

105

come una superclasse astratta per gli oggetti che agiscono come supporto per altri oggetti,

inoltre NSProxy è essenziale nelle architetture di oggetti distribuiti. Poiché tale ruolo è

molto specializzato risulta poco frequente nei programmi Cocoa, quando infatti si fa

riferimento alla classe root spesso si considera NSObject.

Il paragrafo in oggetto si occupa di NSObject, come interagisce con il runtime, il

comportamento base e le interfacce per tutti gli oggetti Cocoa. Fondamentali sono le

dichiarazioni di metodi per l'assegnazione, l'inizializzazione, l'introspector, la gestione

della memoria ed il supporto al runtime, concetti fondamentali per la comprensione di

Cocoa.

4.3.3.1 NSObject

NSObject non ha una superclasse, da essa ereditano molte classi Objective-C. Tali classi

ereditano l'interfaccia base al sistema runtime per il linguaggio Objective-C e le sue

istanze ottengono le funzionalità tali da diventare oggetti.

Anche se non è strettamente una classe astratta NSObject lo è virtualmente, infatti un

oggetto NSObject non può fare nulla di utile al di là di essere un semplice oggetto. Per

aggiungere gli attributi e le funzionalità del programma specifico è necessario creare una o

più classi ereditate da NSObject o da qualsiasi altra classe derivata.

NSObject adotta il protocollo NSObject che abilita l'uso di oggetti di root. Per esempio

NSProxy non deriva da NSObject, ma adotta il protocollo NSObject così da avere

un'interfaccia comune con altri oggetti Objective-C.

4.3.3.2 Classe root e Protocolli

Si è detto che NSObject è sia il nome di una classe che di un protocollo, entrambi

essenziali per definire un oggetto Cocoa. Il protocollo specifica la base di

programmazione delle interfacce richiesta da tutte le classi root in Cocoa, quindi non solo

la classe NSObject utilizza il protocollo omonimo, ma anche NSProxy, l'altra classe di

root. La classe NSObject fornisce le specifiche per la programmazione delle interfacce per

Page 106: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

106

tutti gli oggetti Cocoa che non sono oggetti Proxy.

Un protocollo come NSObject è usato nella maggioranza delle definizioni di oggetti

Cocoa, rendendo possibile l'utilizzo di più classi di root, ognuna delle quali condivide una

interfaccia comune come definito dal protocollo adottato.

Da un altro punto di vista NSObject non è semplicemente un protocollo di root, inoltre la

classe NSObject non adotta formalmente i protocolli NSCopying, NSMutableCopying e

NSCoding, ma dichiara ed implementa metodi ad essi relativi. Nell'header file

NSObject.h, che contiene la definizione della classe NSObject, ci sono anche le

definizioni dei quattro protocolli menzionati precedentemente. Copiare, codificare e

decodificare sono operazioni fondamentali per gli oggetti, molte sottoclassi adottano o

sono conformi a tali protocolli.

Le altre classi possono aggiungere metodi ad NSObject attraverso le categorie, queste

spesso sono protocolli informali usati nelle deleghe. Le categorie permettono ai delegati di

scegliere quali metodi delle categorie implementare.

4.3.3.3 Descrizione dei metodi della classe di root

La classe root NSObject, insieme ai protocolli adottati ed altri protocolli di root,

specificano le seguenti caratteristiche di interfaccia e di funzionamento per tutti gli oggetti

Cocoa non proxy: 1 Allocazione, inizializzazione e duplicazione. Alcuni metodi di NSObject (incluso

alcuni dei protocolli adottati) contribuiscono alla creazione, inizializzazione e

duplicazione di oggetti:

a. Alloc ed allocWithZone: sono metodi che allocano memoria per un oggetto da una

zona di memoria e imposta l'oggetto al punto di runtime di definizione della classe.

b. Il metodo init è il prototipo per l'inizializzazione di oggetti, la procedura che

imposta le variabili istanziate di un oggetto ad un noto stato iniziale. Il metodo di

classe initialize e load assegnano alle classi la possibilità di inizializzarsi.

c. New è un metodo che combina allocazione e inizializzazione.

Page 107: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

107

d. Copy e copyWithZone: sono metodi che fanno copie di ogni oggetto membro di una

classe che implementa tali metodi (dal protocollo NSCopying); mutableCopy e

mutableCopyWithZone: (definiti nel protocollo NSMutableCopying) sono

implementati da classi che costruiscono copie modificabili degli oggetti.

2 Acquisizione e rilascio di oggetti. I metodi che seguono sono particolarmente

importanti per un programma orientato ad oggetti che usa formalismi tradizionali ed

espliciti per la gestione della memoria con modalità memory management:

a. Il metodo retain incrementa un contatore retain dell'oggetto.

b. Il metodo release decrementa un contatore retain dell'oggetto.

3 Il metodo autorelease spesso decrementa un contatore retain di un oggetto, ma in modo

differente.

a. Il metodo retainCount restituisce il valore corrente del contatore retain di un

oggetto.

b. Il metodo dealloc è implementato da una classe per rilasciare le sue istanze delle

variabili degli oggetti e liberare la memoria allocata dinamicamente.

4 Introspezione e comparazione. Molti metodi NSObject abilitano richieste runtime su

di un oggetto. Questi metodi introspettivi aiutano a ricercare la posizione di un oggetto

nella gerarchia della classe, determinare quando implementa un determinato metodo, e

verificare se è conforme ad un particolare protocollo. Alcuni di questi sono solo metodi

di classe.

a. I metodi class e superclass (classi ed istanze) restituiscono la classe e la

superclasse del ricevitore come oggetti classe.

b. É possibile determinare il raggruppamento della classe di un oggetto con i metodi

isKindOfClass: ed isMemberOfClass:. Il secondo metodo serve e verificare se il

ricevitore è una istanza di una specifica classe. Il metodo isSubclassOfClass:

invece verifica la gerarchia della classe.

c. Il metodo respondsToSelector: verifica se il ricevitore implementa un metodo

identificato da un selettore. Il metodo di classe instancesRespondToSelector:

verifica se le istanze di una determinata classe attuano il metodo specificato.

Page 108: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

108

d. Il metodo ConformsToProtocol: verifica se un ricevitore è conforme per ricevere

un protocollo.

e. I metodi isEqual: ed hash sono usati nelle comparazioni di oggetti.

f. Il metodo description abilita un oggetto a restituire una stringa che descrive il suo

contenuto. Questo output è spesso usato durante il debugging (comando “print

object”) ed attraverso le specifiche “%@” per oggetti in formato stringa.

5 Codifica e decodifica di oggetti. I metodi che seguono sono pertinenti alla codifica e

decodifica di oggetti, come parte di un processo di archiviazione:

a. I metodi encodeWithCoder: e initWithCoder: sono gli unici membri del protocollo

NSCoding. Il primo abilita un oggetto a codificare le sue variabili istanziate ed il

secondo abilita un oggetto ad inizializzare sé stesso per decodificare le variabili

istanziate.

b. La classe NSObject dichiara altri metodi relativi alla codifica di oggetti:

classForCoder, replacementObjectForCoder: e awakeAfterUsingCoder:

i. Inoltro di messaggi. Il metodo forwardInvocation: e quelli ad esso

relativi permette ad un oggetto di inoltrare un messaggio ad un altro

oggetto.

ii. Distribuzione di oggetti. Un insieme di metodi che iniziano con

performSelector... abilitano la distribuzione di messaggi dopo uno

specificato ritardo ed a distribuire messaggi (sincroni o asincroni) da un

thread secondario al thread principale.

È importante comunque notare che NSObject implementa molti altri metodi per le classi.

4.3.3.4 Metodi di Classe e metodi di istanza

Il sistema runtime gestisce i metodi della classe di root in modo speciale. I metodi di

istanza definiti nella classe root possono essere realizzati sia da istanze che da classi di

oggetti. Pertanto i metodi di istanza della classe root possono essere usati sia dagli oggetti

Page 109: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

109

di una classe che dalla classe stessa come se fossero metodi di classe. Tale procedura è

possibile a patto che non ci siano metodi con lo stesso nome implementati nella classe che

li invoca.

Ad esempio, una classe potrebbe inviare un messaggio per realizzare i metodi di istanza

respondsToSelector: e performSelector:withObject: di NSObject:

SEL method = @selector(riskAll:);

if ([MyClass respondsToSelector:method])

[MyClass performSelector:method withObject:self];

Si noti che gli unici metodi di istanza disponibili ad una classe sono quelli definiti nella

sua classe root. Nell'esempio riportato, se MyClass avesse sovrascritto

respondsToSelector:, performSelector: e withObject:, queste nuove versioni sarebbero

servite esclusivamente alle proprie istanze, in quanto metodi di istanza. Un oggetto classe

invece avrebbe continuato ad accedere ai metodi di classe definiti da NSObject.

Naturalmente se MyClass avesse implementato respondsToSelector:, performSelector: e

withObject:, come metodi di classe piuttosto che metodi di istanze, allora gli oggetti classe

avrebbero potuto utilizzare queste nuove versioni.

4.3.4 Allocazione e rilascio di oggetti

Objective-C, con il rilascio di Mac OS X 10.5, implementa due metodi per garantire la

persistenza ed il rilascio di oggetti. L'approccio più utilizzato in Mac OS X 10.5 è Garbage

Collection: il sistema di runtime rileva gli oggetti non più necessari e li dispone

automaticamente, tale approccio risulta anche il più semplice nella maggior parte dei casi.

Il secondo approccio, chiamato memory management, si basa sul conteggio dei

riferimenti: ciascuna chiamata che rivendica la proprietà di un oggetto (allocazione,

inizializzazione, copia e trattenuta) deve essere bilanciata da una chiamata che rimuove

tale proprietà (rilascio ed autorilascio). Ogni oggetto ha un contatore che indica il numero

Page 110: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

110

di richieste che riceve, quando tale contatore decresce fino a 0, l'oggetto è deallocato e la

memoria occupata viene liberata.

Nel seguito del capitolo analizzeremo esclusivamente il metodo memory management, in

quanto Garbage Collection non è implementabile in iPhone OS. Bisogna comunque

sottolineare che Garbage Collection ha una gestione delle memoria più semplice di

memory management, rendendo inoltre semplice l'implementazione di metodi accessori.

Un'altra considerazione importante è che i due paradigmi di gestione della memoria non

sono compatibili, quindi non è raccomandabile migrare un'applicazione gestita con

memory management in un programma che cerca di supportare entrambi i metodi, ma

piuttosto è consigliabile costruire una nuova applicazione che supporti Garbage

Collection.

4.3.4.1 Memory management

Nel codice Objective-C di Memory Management un oggetto Cocoa esiste in più di un

ciclo di vita e potenzialmente ha fasi distinte. Un oggetto quindi è allocato, inizializzato ed

usato. È inoltre possibile trattenerlo, copiarlo o archiviarlo ed eventualmente rilasciarlo e

distruggerlo. Verranno analizzate nel seguito le fasi di vita di un oggetto Cocoa.

Ogni oggetto Cocoa porta con sé un numero intero, che indica il numero di altri oggetti

che sono interessati alla sua persistenza, questo numero è chiamato contatore retain

dell'oggetto. Quando si crea un oggetto o usando metodi costruttori delle classi o metodi di

classi come alloc e allocWithZone:, Cocoa realizza due operazioni molto importanti:

1 Configura il puntatore isa dell'oggetto alla classe dell'oggetto, così facendo l'oggetto

verrà integrato nella vista runtime della gerarchia delle classi.

2 Configura il contatore retain dell'oggetto ad uno, una sorta di variabile nascosta gestita

dal runtime. Si presuppone che il creatore dell'oggetto sia interessato alla sua

persistenza.

Successivamente all'allocazione generalmente si inizializza l'oggetto impostando le istanze

Page 111: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

111

delle sue variabili ad accettabili valori iniziali. NSObject dichiara il metodo init come

prototipo per questo scopo. L'oggetto è così pronto per essere usato, è possibile quindi

inviargli messaggi, inoltrarlo ad un altro oggetto e così via. È da notare comunque che

spesso si ingloba l'espressione del messaggio di alloc all'interno del messaggio di init (o di

altri inizializzatori) come nel seguente esempio:

id anObj = [[MyClass alloc] init];

Quando si rilascia un oggetto, attraverso un messaggio release, NSObject decrementa il

suo puntatore retain, se tale valore diventa zero l'oggetto viene deallocato in due fasi. In

una prima fase, il metodo dealloc dell'oggetto è invocato per rilasciare le istanze delle

variabili e liberare la memoria allocata dinamicamente. Successivamente il sistema

operativo distrugge l'oggetto e reclama la memoria che era occupata dall'oggetto stesso. È

importante notare che non si dovrebbe mai invocare direttamente un metodo dealloc di un

oggetto.

Nel caso in cui, ricevuto un oggetto, si richiede il suo mantenimento, il contatore retain

dell'oggetto verrà incrementato a due, saranno quindi necessari due messaggi di release

per rilasciare tale oggetto. In Figura 15 è indicato questo meccanismo.

Figura 14: Contatore retain

Page 112: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

112

Nel caso descritto in Figura 15, il creatore dell'oggetto non ha necessità di trattenerlo in

quanto lo possiede già, ma se questo è stato creato per inviarlo ad un altro oggetto tramite

un messaggio la situazione cambia. In un programma Objective-C è possibile ricevere

oggetti da altri oggetti ed inviarli per messaggio ad altri oggetti ancora. Questa

caratteristiche richiede che se un primo oggetto invia un oggetto ad un terzo che fa da

ricevente, il primo non può rilasciare il secondo oggetto prematuramente mentre questo è

utilizzato dall'ultimo ricevente.

Nel caso in cui il ricevente dell'oggetto necessita di conservarlo anche quando il

programma ha concluso il suo scopo può farlo, incrementando il contatore retain

dell'oggetto. In tal modo se il creatore dell'oggetto lo rilascia questo non verrà deallocato

ed il ricevente diventa il responsabile dello stesso, potrà così deallocarlo in un momento

successivo. Nella Figura 16 è descritta questa dinamica.

Anziché mantenere un oggetto è possibile copiarlo attraverso l'invio di una copia o con un

messaggio copyWithZone:, molte sottoclassi che incapsulano un dato utilizzano questo

Figura 15: Trattenuta di un oggetto ricevuto

Page 113: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

113

protocollo. Copiando un oggetto, non solo lo si duplica ma si riporta il contatore retain ad

uno (come indicato in Figura 17).

La copia può essere superficiale o profonda, dipende dalla natura dell'oggetto e dal suo

utilizzo. Una copia profonda duplica l'oggetto e le sue variabili istanziate, mentre una

copia superficiale duplica solo i riferimenti a tali variabili.

In termini di utilizzo, ciò che differenzia una copia dall'originale è che adesso l'oggetto è

gestito soltanto dal nuovo proprietario, che può cambiare tale copia senza preoccuparsi

della sua origine.

Generalmente si utilizza questa tecnica con gli oggetti mutabili come un

NSMutableString, mentre per quelli immutabili, copiarli o trattenerli è praticamente

equivalente.

In una tale gestione degli oggetti si potrebbe verificare un problema nel suo ciclo di vita.

Se infatti un oggetto ne crea un altro e poi lo invia ad un terzo potrebbe non sapere quando

poterlo rilasciare in sicurezza, ci potrebbero essere infatti molteplici riferimenti all'oggetto

Figura 16: Oggetti copiati e ricevuti

Page 114: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

114

nello stack delle chiamate e queste potrebbero essere sconosciute alla creazione

dell'oggetto. Se l'oggetto creatore lo rilasciasse ed altri oggetti inviassero un messaggio

all'oggetto distrutto il programma potrebbe andare in crash. Per evitare ciò Cocoa

introduce un meccanismo per dilazionare la deallocazione, chiamata “autorilascio”.

L'autorilascio si avvale di autorelease pool (definite dalla classe NSAutoreleasePool). Un

autorelease pool è una collezione di oggetti all'interno di un ambito definito

esplicitamente, contrassegnati per il loro eventuale rilascio, le autorelease pool possono

essere nidificate. Quando si invia un messaggio di autorilascio ad un oggetto si mette il

riferimento all'oggetto nella autorelease pool del suo ambito. Tale oggetto è ancora valido,

così che altri oggetti che rientrano nell'ambito di applicazione definito dall' autorelease

pool possono inviargli messaggi. Quando un programma conclude la sua esecuzione

l'autorelease pool viene rilasciata e con essa tutti gli oggetti al suo interno (guarda figura

18). Non è comunque sempre necessario configurare un autorelease pool in quanto

Application Kit lo crea automaticamente nell'ambito dell'applicazione.

Figura 17: Autorelease Pool

Page 115: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

115

Poiché in iPhone OS le applicazioni sono eseguite in un ambiente con memoria limitata

l'uso dell'autorilascio è sconsigliato, sopratutto in metodi o blocchi di codice (come i cicli)

in cui si creano molti oggetti, invece è consigliato il rilascio esplicito ovunque sia

possibile.

In sostanza la politica di proprietà degli oggetti può essere sintetizzata nel seguente modo:

1 Se si crea un oggetto allocandolo ed inizializzandolo (ad esempio con la direttiva

[[MyClass alloc] init]) si è proprietari dell'oggetto e responsabili del suo rilascio. Questo

ruolo si verifica anche con l'utilizzo del metodo pubblico new di NSObject.

2 Se si copia un oggetto, si è proprietari della copia e responsabili del suo rilascio.

3 Se si trattiene un oggetto, si è parzialmente proprietari e bisogna rilasciarlo quando non è

più necessario trattenerlo.

Viceversa, se si riceve un oggetto da un altro oggetto, non si è proprietari di questo e non si

dovrebbe rilasciarlo.

È importante notare come sia poco utile non seguire la politica appena descritta, in quanto

il programma potrebbe rivelarsi poco efficiente. Non deallocare oggetti creati, copiati o

trattenuti infatti rende il programma avido di memoria o addirittura andare in crash nel

momento in cui si invia un messaggio ad un oggetto deallocato in maniera non controllata.

Altra considerazione da fare è che questo tipo di problemi prevedono tempi di debug

molto lunghi per essere individuati.

4.3.5 Archiviazione di oggetti

Un'ulteriore possibile operazione da effettuare su di un oggetto durante il suo ciclo di vita

è l'archiviazione. Questo vuol dire che si converte la rete di oggetti di un programma (che

diventa un oggetto grafico) in una forma persistente, generalmente un file. Si salva quindi

l'identità e la rete di collegamenti di ciascun oggetto del grafico. Quando il programma è

recuperato il suo oggetto grafico è ricostruito dal suo archivio. Per essere incluso

Page 116: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

116

nell'archiviazione e nel recupero un oggetto deve poter codificare e decodificare le sue

variabili usando i metodi della classe NSCoder, a questo scopo NSObject utilizza il

protocollo NSCoding.

4.3.6 Usare Objective

Un programma viene eseguito attraverso lo scambio di messaggi, un oggetto invia

messaggi ad altri oggetti. Attraverso i messaggi, l'oggetto mittente richiede qualcosa

all'oggetto ricevitore (receiver), può richiedere che il ricevitore svolga un'azione,

restituisca un oggetto, un valore o altre possibili richieste.

Objective-C adotta una forma sintattica unica per i messaggi:

NSEnumerator *enm = [sorted_args objectEnumerator];

Il messaggio è sul lato destro dell'espressione, tra le parentesi quadre. La voce più a

sinistra nell'espressione del messaggio è il ricevitore, una variabile o una espressione che

rappresenta l'oggetto al quale è stato inviato il messaggio. In questo caso, il ricevitore è

sorted_args, un'istanza della classe NSArray.

Dopo il ricevitore c'è proprio il messaggio, in questo caso objectEnumerator. Il messaggio

ObjectEnumerator invoca un metodo di un oggetto sorted_args denominato

objectEnumerator, che restituisce un riferimento ad un oggetto detenuto dalla variabile

enm sul lato sinistro dell'espressione. Questa variabile è di tipo statico come un'istanza

della classe NSEnumerator. È possibile uno schema di questa dichiarazione:

NSClassName variable[receiver message];

Tuttavia, questo schema è semplicistico e non molto accurato, un messaggio è costituito da

un nome di selettore e dai parametri del messaggio. Il runtime Objective-C utilizza un

nome di selettore, come objectEnumerator dell'esempio precedente, per cercare il selector

nella tabella di dispach, al fine di trovare il metodo da richiamare. Un selettore (SEL) è un

Page 117: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

117

identificatore univoco che rappresenta un metodo. Poichè è così strettamente connesso, il

nome utilizzato per cercare il selettore è spesso chiamato come il selettore stesso. La

dichiarazione di cui sopra può quindi essere correttamente riscritta:

NSClassName variable[receiver selector];

I messaggi spesso sono parametri, o argomenti. Un messaggio con un unico argomento

appone due punti dopo il nome del selettore e pone l'argomento alla destra dei due punti.

Una parola chiave si conclude con due punti, l'argomento viene posto dopo di essi. Così

potremmo costruire l'espressione di un messaggio con un unico argomento:

NSClassName variable[receiver keyword: argument];

Se un messaggio ha più argomenti, il selettore ha più keyword. Un nome di selettore

include tutte le keyword, include i due punti ma non include nient'altro, come il tipo di

ritorno o il tipo di parametro.

L'espressione di un messaggio con più argomenti potrebbe essere la seguente:

NSClassName variable[receiver keyword2: arg1 keyword2: arg2];

come i parametri di funzione, il tipo di un argomento deve corrispondere al tipo

specificato nel metodo dichiarato. Prendiamo come esempio la sintassi del seguente

messaggio del programma SimpleCocoaTool:

NSCountedSet *cset = [[NSCountedSet alloc]

initWithArray:args];

Nell'espressione si ha che args, che è spesso un'istanza della classe NSArray, è l'argomento

del massaggio chiamato initWithArray:.

L'esempio citato è interessante in quanto illustra la nidificazione. Con Objective-C, è

possibile nidificare un messaggio all'interno di un altro messaggio; l'oggetto restituito

dall'espressione di un messaggio è usato come il ricevitore dall'espressione del messaggio

che racchiude. Così, per interpretare espressioni nidificate di messaggi, si inizia con

Page 118: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

118

l'espressione interna e si lavora verso l'esterno. L'interpretazione della dichiarazione di cui

sopra potrebbe essere:

1. Il messaggio alloc è inviato alla classe NSCountedSet, che crea un'istanza non

inizializzata della classe.

2. Il messaggio initWithArray: è inviato ad un'istanza non inizializzata, che si inizializza

con l'array args e restituisce un riferimento a sé stesso.

Si consideri ora quest'espressione dalla routine main di SimpleCocoaTool:

NSArray *sorted_args = [[cset allObjects]

sortedArrayUsingSelector:@selector(compare:)];

In quest'espressione è degno di nota l'argomento del messaggio

sortedArrayUsingSelector:. Questo argomento richiede l'uso della direttiva di compilatore

@selector per creare un selettore da essere usato come argomento.

Riguardiamo ora la terminologia di messaggi e metodi. Un metodo è essenzialmente una

funzione definita ed implementata da una classe di cui il destinatario del messaggio è

membro. Un messaggio è un nome di selettore, costituito anche di una o più parole chiave,

e dai suoi argomenti. Un messaggio viene inviato ad un ricevitore e ciò comporta

l'invocazione o l'esecuzione del metodo.

La sintassi del messaggio comprende sia il ricevitore che il messaggio, in figura 19 è

spiegata questa relazione.

Page 119: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

119

Figura 18: sintassi di un messaggio

Objective-C utilizza un numero definito di tipi e letterali che non si trova in ANSI C e che,

in alcuni casi, sostituiscono le loro controparti ANSI C.

La Tabella 3 descrive questi elementi ed i letterali ammessi per ogni tipo.

Tipi Descrizioni e letterali

Id Un tipo dinamico, il suo letterale negativo è Nil.

Class Classe di tipo dinamico, il suo letterale negativo è Nil.

SEL Il tipo dato di un selettore (typedef). Il suo letterale negativo è NULL.

BOOL Un tipo Booleano, il suo valore letterale è YES o NO.

Tabella 2: Elementi e descrizioni

Nel flusso di controllo delle dichiarazioni di un programma, è possibile verificare la

presenza (o l'assenza) di un determinato valore negativo per scegliere come procedere. Per

esempio, nel programma SimpleCocoaTool, si testa implicitamente un oggetto variabile

word per determinare la presenza di un oggetto restituito, quindi dell'assenza di un valore

nullo:

while (word = [enm nextObject]) {

printf("%s\n", [word UTF8String]);

}

Page 120: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

120

In Objective-C è possibile inviare un messaggio nil senza avere nessun effetto negativo, il

valore di ritorno garantisce la prosecuzione delle operazioni come se fosse stato restituito

un oggetto.

L'ultima caratteristica da notare in Objective-C è poco evidente, ma si guardi il seguente

stralcio di codice:

NSEnumerator *enm = [sorted_args objectEnumerator];

E lo si paragoni al seguente:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

Apparentemente sembrano identici, entrambi restituiscono un riferimento ad un oggetto,

tuttavia c'è una grossa differenza semantica (per la gestione della memoria), che ha a che

fare con la proprietà degli oggetti restituiti e con la responsabilità del proprio rilascio.

Nella prima dichiarazione non viene restituito l'oggetto, nel secondo stralcio di codice il

programma crea l'oggetto e lo possiede. L'ultima cosa che fa il programma è inviare un

messaggio di rilascio all'oggetto creato, così da liberarlo. L'altro e unico oggetto creato

esplicitamente (ad esempio NSCountedSet) è esplicitamente rilasciato alla fine del

programma SimpleCocoaTool.

4.4 Objective-C: aspetti avanzati

Objective-C è dotato di due caratteristiche per il linguaggio base che sono potenti

strumenti di sviluppo software: Categorie e Protocolli. Alcune estensioni introducono

tecniche differenti per la dichiarazione di metodi e della loro associazione alle classi. Altre

tecniche offrono strade semplici per dichiarare ed accedere alle proprietà degli oggetti,

enumerare velocemente collection, gestire le eccezioni e migliorare altre operazioni.

Page 121: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

121

4.4.1 Categorie

Le categorie permettono di attribuire metodi alle classi senza dover costruire sottoclassi, i

metodi nelle categorie diventano parti del tipo di classe, entro l'ambito del programma, e

sono ereditate da tutte le sottoclassi. Non ci sono differenze al tempo di esecuzione tra i

metodi originali e quelli aggiunti, è possibile inoltre inviare un messaggio ad ogni istanza

della classe (o una sua sottoclasse) per invocare un metodo definito in una categoria.

Le categorie sono molto più che un modo conveniente di aggiungere azioni alle classi, è

possibile usare le categorie per raggruppare metodi, e dividerli in categorie differenti. Le

categorie sono altresì uno strumento utile per organizzare classi molto grandi e si possono

anche mettere diverse categorie in diversi file sorgenti se, per esempio, ci sono diversi

sviluppatori che lavorano sulla stessa classe.

Dichiarare ed implementare una categoria è molto simile che farlo per una sottoclasse,

sintatticamente l'unica differenza è il nome della categoria che segue la direttiva

@interface o @implementation ed è scritto tra parentesi. Se per esempio vogliamo

aggiungere un metodo alla classe NSArray che stampa la descrizione di collection in più

di una struttura, nell'header file della categoria bisognerà scrivere un codice simile al

seguente:

#import <Foundation/NSArray.h> // if Foundation not already

imported

@interface NSArray (PrettyPrintElements)

- (NSString *)prettyPrintDescription;

@end

Nel file di implementazione invece il codice sarà:

#import “PrettyPrintCategory.h”

Page 122: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

122

@implementation NSArray (PrettyPrintElements)

- (NSString *)prettyPrintDescription {

// implementation code here...

}

@end

Bisogna comunque sottolineare le limitazioni che le categorie hanno, non è possibile

infatti usare una categoria per aggiungere istanze di nuove variabili alle classi. Benchè una

categoria di metodi può sovrascrivere un metodo esistente, non è raccomandabile farlo,

sopratutto se si vogliono incrementare le caratteristiche. Una ragione per questa cautela è

che i metodi delle categorie sono parti delle interfacce delle classi, e non c'è modo di

inviare un messaggio per realizzare le caratteristiche già definite dalla classe. Se risultasse

necessario cambiare un metodo esistente, è consigliabile creare una sottoclasse.

È possibile definire le categorie per aggiungere metodi alla classe root, NSObject. Tali

metodi sono disponibili per tutte le istanze e le classi di oggetti che sono collegati al

codice. Protocolli informali, la base per il meccanismo di delega di Cocoa, sono dichiarati

come categorie di NSObject. Questo approccio però comporta dei rischi, in quanto queste

caratteristiche aggiunte ad ogni oggetto attraverso una categoria di NSObject, potrebbero

comportare conseguenze che non sempre possono essere anticipate, portando al blocco del

programma, corruzione dei dati, o conseguenze peggiori.

4.4.2 Protocolli

Le interfacce di categorie e classi dichiarano metodi associati ad una particolare classe. I

protocolli, formali ed informali invece dichiarano metodi indipendenti da una specifica

classe ma che qualunque classe può implementare ed utilizzare.

I protocolli quindi sono utili in almeno tre situazioni:

1 per dichiarare metodi che si prevede di implementare al di fuori di una specifica classe

Page 123: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

123

2 per dichiarare l'interfaccia ad un oggetto che nasconde la propria classe

3 per collegare classi che non sono gerarchicamente connesse

Un protocollo in sostanza è una lista di dichiarazioni di metodi slegati da una specifica

classe. Ad esempio se si costruisce un protocollo che nei suoi metodi gestisce le azioni del

mouse, ogni classe che vuole sfruttare le caratteristiche del mouse adotterà tale protocollo

ed implementerà i suoi metodi. I protocolli quindi rendono libera una dichiarazione di

metodo dalle classi e dalle loro gerarchie. L'unico vincolo che ha una classe per poter

utilizzare il metodo dichiarato è la conformità al protocollo. I protocolli sono inoltre

estremamente utili in progetti divisi in più blocchi o quando incorporano oggetti di altri

progetti.

Il protocollo è anche il modo per una classe di dichiarare un'interfaccia quando nasconde

la propria identità. Le interfacce possono inoltre esporre tutti o solo un range di servizi

disponibili della classe che la offre. Qualunque altra classe in questo modo può

implementare i metodi del protocollo e così accedere ai servizi pubblicati. Con un

protocollo quindi è possibile mettere in comunicazione classi non relazionate in alcun

modo.

Un protocollo può inoltre dichiarare metodi per un oggetto di una classe “sconosciuta”.

Tale oggetto sconosciuto potrebbe infatti rappresentare un set di funzioni. Un esempio di

protocollo di oggetti sconosciuti potrebbe verificarsi nell'eventualità di dover inviare un

messaggio ad un oggetto remoto, quindi di un'applicazione esterna. Ovviamente in tale

applicazione deve essere implementato un protocollo atto a ricevere tale messaggio.

Esistono due tipi di protocolli: formale ed informale. I protocolli informali sono stati

brevemente introdotti nel paragrafo 4.4.1 “Categorie”. Sono le categorie in NSObject, di

conseguenza ogni oggetto con NSObject come sua superclasse implicitamente adotta

l'interfaccia pubblicata nella categoria.

Per utilizzare un protocollo informale, una classe non deve implementare tutti i suoi

metodi, ma soltanto quello a cui è interessato, per far funzionare tale protocollo inoltre la

Page 124: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

124

classe che lo dichiara deve ottenere una risposta positiva a respondsToSelector (messaggio

ricevuto dall'oggetto destinazione) e lo deve ricevere prima di inviare il messaggio con

l'oggetto del protocollo. (Se l'oggetto di destinazione non implementa il metodo ci sarà

una eccezione di runtime.)

I protocolli formali sono generalmente quelli che in Cocoa vengono definiti come

“Protocolli”, consentono ad una classe di dichiarare formalmente una lista di metodi come

interfacce di servizi offerti. Il linguaggio Objective-C ed il sistema di runtime supportano i

protocolli formali; il compilatore può verificare i tipi basati sui protocolli, e gli oggetti

possono al tempo di esecuzione verificare la conformità al protocollo. I protocolli formali

hanno una loro terminologia ed una sintassi, la terminologia è differente per provider

(fornitore) e client:

1 Un provider, generalmente una classe, dichiara il protocollo formale.

2 Un client classe, adotta un protocollo formale e così facendo si impegna ad attuare tutti i

metodi del protocollo.

3 Una classe si dice conforme ad un protocollo formale se adotta il protocollo o lo eredita

da una classe che lo adotta, i protocolli sono quindi ereditati dalle sottoclassi.

Sia la dichiarazione che l'adozione di un protocollo hanno una loro sintassi in Objective-C,

per dichiarare un protocollo è necessario utilizzare la direttiva del compilatore @protocol.

L'esempio seguente (Riquadro 11) mostra la dichiarazione del protocollo NSCoding,

nell'header file NSObject.h del framework Foundation.

Page 125: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

125

@protocol NSCoding

- (void)encodeWithCoder:(NSCoder *)aCoder;

- (id)initWithCoder:(NSCoder *)aDecoder;

@end

Riquadro 11: dichiarazione di Protocollo

Objective-C 2.0 aggiunge caratteristiche ai protocolli formali che permettono la possibilità

di dichiarare metodi opzionali esattamente come quelli richiesti. In Objective-C 1.0

invece, l'adozione di un protocollo, implicava l'implementazione di tutti i metodi del

protocollo. Nei protocolli di Objective-C 2.0 i metodi sono implicitamente considerati

required e possono essere esplicitamente indicati come tali attraverso l'uso della direttiva

@required, allo stesso tempo è possibile marcare blocchi dei metodi del protocollo come

opzionali, attraverso l'uso della direttiva @optional. Tutti i metodi dichiarati dopo questa

direttiva, fino a che non si fa riferimento ancora a @required, sono implementati come

opzionali. Consideriamo la seguente dichiarazione:

@protocol MyProtocol

// implementation this method is required implicitly

- (void)requiredMethod;

@optional

// implementation of these methods is optional

- (void)anOptionalMethod;

- (void)anotherOptionalMethod;

@required

// implementation of this method is required

- (void)anotherRequiredMethod;

@end

La classe che dichiara il protocollo generalmente non implementa i suoi metodi.

Page 126: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

126

Comunque dovrebbe invocare tali metodi nelle istanze delle classi conformi al protocollo.

Prima di invocare metodi opzionali, deve verificare che sono implementati usando

respondsToSelector.

Una classe adotta un protocollo specificando il nome, tra parentesi angolari (<...>), alla

fine della direttiva @interface, appena dopo la superclasse. Una classe può adottare

protocolli multipli delimitati con le virgole. Di seguito è indicato come la classe NSData

Foundation adotta tre protocolli.

@interface NSData : NSObject <NSCopying, NSMutableCopying,

NSCoding>

Con l'adozione di questi protocolli, NSData si impegna ad implementare tutti i metodi

required dichiarati nei protocolli, può anche scegliere di applicare metodi contrassegnati

con la direttiva @optional. Anche le Categorie possono adottare protocolli e la loro

adozione diventa parte della definizione della classe associata.

I tipi Objective-C sono raggruppati sulla base dei protocolli ai quali sono conformi così

come per le classi dalle quali derivano. È possibile verificare se una classe è conforme ad

un particolare protocollo con l'invio di un messaggio conformsToProtocol:

if ([anObject conformsToProtocol:@protocol(NSCoding)]) {

// do something appropriate

}

In una dichiarazione di un tipo (metodo, istanza di variabile o funzione) è possibile

specificare la conformità ad un protocollo come parte del tipo, si ottiene quindi un altro

livello di tipo di controllo da parte del compilatore, più astratto perchè non è legato ad una

Page 127: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

127

particolare implementazione.

Si utilizza la stessa sintassi come convenzione per l'adozione di protocolli: si inserisce il

nome del protocollo tra parentesi angolari per specificare la conformità del protocollo al

tipo. Spesso si utilizza questa sintassi per gli oggetti dinamici:

- (void)draggingEnded:(id <NSDraggingInfo>)sender;

Nel codice l'oggetto associato all'argomento può essere di ogni tipo di classe, ma deve

essere conforme al protocollo NSDraggingInfo.

Cocoa fornisce diversi esempi di altri protocolli diversi da quelli indicati fin'ora, un

protocollo interessante è NSObject, non sorprende che lo adotta la classe NSObject.

Attraverso questo protocollo l'altra classe di root, NSProxy, può interagire con le parti del

runtime Objective-C essenziali per il conteggio, introspection ed altri aspetti base dei

comportamenti degli oggetti.

4.4.3 Dichiarazione delle proprietà

Nel dichiarare la struttura di un oggetto, bisogna considerare alcune proprietà. Tali

proprietà sono attributi degli oggetti stessi, come titolo e colore, e relazioni con altri

oggetti. Nel codice tradizionale Objective-C è possibile definire proprietà dichiarando

istanze di variabili, attraverso l'incapsulamento e l'implementazione di metodi accessori

getter e setter per i valori di queste variabili. Questa procedura è tediosa e rischiosa,

soprattutto se riguarda la gestione della memoria.

Objective-C 2.0, introdotto in Mac OS X 10.5, offre una sintassi per dichiarare le proprietà

e specificare come accedervi. Dichiarare una proprietà quindi diventa come sintetizzare

metodi come il getter ed il setter. Attraverso le proprietà quindi non è più necessario

implementare i metodi accessori. Ci sono tre aspetti della sintassi delle proprietà:

dichiarazione, implementazione ed accesso.

Page 128: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

128

E' possibile dichiarare proprietà ovunque sia possibile dichiarare metodi nelle sezioni

dichiarative di classi, categorie e protocolli. La sintassi per dichiarare una proprietà è:

@property(attributes...)type propertyName

Dove attibutes... sono uno o più attributi opzionali (se multipli sono separati da virgole),

che influenzano come il compilatore registra le variabili istanziate e sintetizza i metodi

accessori.

L'elemento type specifica un tipo oggetto, un tipo dichiarato o scalare come NSString,

come un id, NSRange o float. La proprietà deve essere sostenuta da una variabile

istanziata dello stesso tipo e nome.

I possibili attributi nelle dichiarazioni di una proprietà sono:

Attributi Effetti

getter=getterName

setter=setterName

Specifica il nome dei metodi accessori getter e setter.

Bisogna specificare questi attributi quando si implementa un metodo

accessorio personalizzato e si vuole modificare il suo nome.

Readonly Indica che può essere solo letta, non scritta. Il compilatore non

sintetizza un accessorio setter.

Readwrite Indica che la proprietà può essere letta e scritta, questo attributo è di

default, se non è specificato readonly.

Assign

Specifica che una semplice assegnazione potrebbe essere usata

nell'implementazione del setter. Questo attributo è di default. Se le

proprietà sono dichiarate in un programma non-garbage-collected, è

necessario conservare o copiare le proprietà degli oggetti.

Retain Specifica che retain deve essere inviato alla proprietà (che deve

essere di un tipo oggetto) al momento dell'assegnazione, inoltre retain

Page 129: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

129

è un no-op in un ambiente garbage-collected.

Copy

Specifica che copy deve essere inviato alla proprietà (che deve essere

un tipo oggetto) al momento dell'assegnazione. La classe dell'oggetto

deve implementare il protocollo NSCopying.

Nonatomic

Specifica che i metodi accessori sono sintetizzati come nonatomic. Di

default quindi tutti i metodi accessori sono atomici, un metodo getter

è garantito per restituire un valore valido, anche quando ci sono in

esecuzione altri thread contemporaneamente.

Se non si specificano attributi e si specifica @synthesize per l'implementazione, il

compilatore sintetizza metodi setter e getter per le proprietà che usano assegnazioni

semplici e che hanno propertyName per il getter e setPropertyName per il setter.

Nel blocco @implementation di una definizione di classe, è possibile usare direttive

@dynamic e @synthesize per controllare quando il compilatore sintetizza metodi accessori

per particolari proprietà.

Entrambe le direttive hanno la stesa sintassi generale :

@dynamic propertyName [, propertyName2...];

@synthesize propertyName [, propertyName2...];

La direttiva @dynamic dice al compilatore che è stato implementato un metodo accessorio

per una proprietà, diretto o dinamico. La direttiva @synthesize d'altro canto dice al

compilatore di sintetizzare i metodi setter e getter se non compaiono nel blocco

@implementation. La sintassi per @syntetize spesso include un'estensione che permette di

nominare una proprietà differentemente dalla sua variabile istanziata. Consideriamo la

seguente dichiarazione:

Page 130: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

130

@synthesize title, directReports, role = jobDescrip;

Questa dichiarazione dice al compilatore di sintetizzare metodi accessori per le proprietà

title, diretcReports e role, e di usare jobDescrip per indicare la proprietà role.

In conclusione la caratteristiche delle proprietà in Objective-C supportano una sintassi

semplificata per i metodi accessori (getting e setting) attraverso l'uso di notazioni puntate e

di semplici assegnazioni. Bisogna notare infine che l'uso delle notazioni puntate funziona

solo con attributi e relazioni semplici uno-ad-uno, non con relazioni multiple.

Pochi esempi bastano a dimostrare quanto sia facile ottenere i valori delle proprietà e

l'utilizzo di questa sintassi:

NSString *title = employee.title; // assigns employee title to

local variable

employee.ID = "A542309"; // assigns literal string to employee ID

// gets last name of this employee's manager

NSString *lname = employee.manager.lastName;

4.4.4 Fast Enumeration

“Fast enumeration” (enumerazione veloce) è una caratteristica introdotta in Objective-C

2.0 che restituisce un modo sintetico per numerare efficientemente le collection

(collezioni). Questo metodo è estremamente più veloce del classico uso di oggetti

NSEnumerator per scorrere attraverso array, set e dizionari. Inoltre garantisce sicurezza,

come mutation guard, che previene modifiche alle collection durante una enumerazione,

sollevando un'eccezione al tentativo di mutazione.

La sintassi per la numerazione veloce è simile a quella usata nei linguaggi di scripting

come Perl e Ruby, ci sono due versioni supportate:

Page 131: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

131

for ( type newVariable in expression ) { statements }

e

type existingVariable;

for( existingVariable in expression ) { statements }

L'espressione deve valutare un oggetto la cui classe è conforme al protocollo

NSFastEnumeration. L'implementazione di fast enumeration è condivisa tra il runtime

Objective-C ed il framework Foundation. Foundation dichiara il protocollo

NSFastEnumeration, le classi collection di Foundation (NSArray, NSDictionary, e NSSet)

e la classe NSEnumerator adottano tale protocollo. Altre classi che detengono collezioni di

altri oggetti, comprese le classi personalizzate, possono adottare NSFastEnumeration per

sfruttare questa caratteristica.

Il seguente stralcio di codice illustra come sia possibile usare l'enumerazione veloce con

oggetti NSArray e NSSet:

NSArray *array = [NSArray arrayWithObjects:

@"One", @"Two", @"Three", @"Four", nil];

for (NSString *element in array) {

NSLog(@"element: %@", element);

}

NSSet *set = [NSSet setWithObjects:

@"Alpha", @"Beta", @"Gamma", @"Delta", nil];

NSString *setElement;

for (setElement in set) {

NSLog(@"element: %@", setElement);

}

Page 132: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

132

4.4.5 Selector

Come introdotto nel paragrafo 4.3.1 “I vantaggi di Objective-C”, i selector sono elementi

della tabella di dispach contenuta nella struttura di ogni classe.

Quando un oggetto riceve un messaggio, attraverso il puntatore isa accede alla propria

classe per cercare nella tabella di dispach il selector del metodo da attuare. Nel caso in cui

tale selector non venga trovato la ricerca procede attraverso il puntatore alla superclasse

lungo tutta la catena gerarchica. Tale meccanismo viene realizzato quando il metodo da

eseguire viene ricavato al tempo di esecuzione.

Bisogna notare altre due caratteristiche che velocizzano lo scambio di messaggi al tempo

di esecuzione. Innanzitutto il sistema runtime memorizza i selector e gli indirizzi dei

metodi usati. Vengono memorizzati in modo separato classe per classe, permettendo di

memorizzare i selector sia dei metodi implementati nella classe sia quelli ereditati. In tal

modo il sistema runtime, quando un oggetto riceve un messaggio, cerca il selector prima

tra quelli già utilizzati, se non lo trova procede con la ricerca all'interno della tabella di

dispach della classe.

Per migliorare l'efficienza inoltre, all'interno del codice compilato, non si associa ai

selector il nome completo del metodo a cui fanno riferimento. Il compilatore scrive nella

tabella il metodo e gli attribuisce un nome di selector univoco. In tal modo non esistono

selector uguali ed allo stesso tempo i metodi con lo stesso nome hanno lo stesso selector.

Successivamente alla compilazione i selector sono identificati da un tipo di dato speciale

SEL che si distingue dagli altri tipi dati. Un selector valido non assume mai valore nullo.

4.4.6 Creazione di oggetti

La creazione di un oggetto Cocoa avviene in due fasi: allocazione ed inizializzazione.

Senza di esse generalmente un oggetto non è usabile, di conseguenza nella maggior parte

dei casi l'inizializzazione segue sempre l'allocazione nonostante giochino ruoli differenti

nella formazione di un oggetto.

Page 133: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

133

4.4.6.1 Allocazione

Quando si alloca un oggetto Cocoa si destina memoria all'oggetto da una regione di

memoria virtuale associata all'applicazione. Per valutare la quantità di memoria da allocare

si prendono in considerazione le variabili di istanza dell'oggetto, incluso i tipi ed il loro

ordine, come specificato dalla classe dell'oggetto.

Per allocare un oggetto bisogna inviare un messaggio alloc o allocWithZone: alla classe

dell'oggetto, sarà restituita un'istanza grezza (non inizializzata) di quella classe. La

variante alloc utilizza la zona di memoria destinata all'applicazione. Un messaggio di

allocazione compie anche altre operazioni:

• Configura il contatore retain dell'oggetto ad uno.

• Inizializza il puntatore isa dell'oggetto indicandogli la classe dell'oggetto stesso, un

oggetto deve essere compilato dalla definizione della classe.

• Inizializza tutte le variabili a zero (o valori equivalenti come nil, NULL e 0.0).

L'oggetto isa è ereditato da NSObject, così è in comune a tutti gli oggetti Cocoa. Dopo

l'allocazione viene configurato l'isa alla classe dell'oggetto che così viene integrato nella

vista runtime della gerarchia dell'ereditarietà delle classi e nella rete di oggetti (classi od

istanze) che costituiscono il programma. Conseguentemente un oggetto può trovare tutte le

informazioni di cui necessita al tempo di esecuzione, come un altro posto nella gerarchia,

il protocollo a cui sono conformi altri oggetti o ancora le implementazioni dei metodi che

possono servire per rispondere ad un messaggio.

In sostanza per “allocazione” non si intende solo l'allocazione della memoria per un

oggetto, ma l'inizializzazione di due piccoli ma molto importanti attributi di tutti gli

oggetti: la variabile puntatore isa ed il suo contatore retain. Inoltre si inizializzano a zero

tutte le variabili ad esso associate, ma l'oggetto non è ancora usabile, metodi di

inizializzazione come init restituiscono l'oggetto usabile, ricco di tutte le sue

caratteristiche.

Page 134: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

134

4.4.6.2 Inizializzazione

L'inizializzazione imposta le variabili di istanza di un oggetto a valori iniziali coerenti per

le variabili stesse. Inoltre si possono allocare e disporre altre risorse globali di cui l'oggetto

ha bisogno, caricandole da una risorsa esterna come un file. Ogni oggetto che dichiara una

variabile dovrebbe implementare un metodo di inizializzazione, a meno che non sia

sufficiente l'inizializzazione di default che imposta tutte le variabili a zero. Se inoltre un

oggetto non implementa un metodo di inizializzazione, Cocoa invoca il metodo

dell'oggetto a lui più vicino dal punto di vista gerarchico.

4.4.6.2.1 Forme di inizializzazione

NSObject dichiara il prototipo init per le inizializzazioni, è un tipo di metodo che

restituisce un oggetto di tipo id. Alcune sottoclassi infatti utilizzano init quando non

richiedono ulteriori dati per inizializzare i propri oggetti, spesso invece l'inizializzazione

dipende da dati esterni per impostare un oggetto al suo stato iniziale. Per esempio se si è

costruiti una classe Account, per inizializzare un oggetto account è necessario fornire al

metodo di inizializzazione il numero dell'account. Questo vuol dire che i metodi di

inizializzazione possono avere uno o più argomenti di ingresso, l'unico vincolo posto è che

il nome inizi con “init”. In questo paragrafo si farà riferimento ad un generico

inizializzatore indicandolo con “init...”.

Bisogna inoltre notare che invece di implementare un metodo di inizializzazione con

argomenti in ingresso è anche possibile che una sottoclasse implementi solo un semplice

metodo init e successivamente usi un metodo accessorio set per impostare lo stato iniziale

dell'oggetto.

Cocoa offre numerosi esempi di inizializzatori con argomenti, di seguito ne sono elencato

alcuni:

• (id)initWithArray:(NSArray *)array; (da NSSet)

• (id)initWithTimeInterval:(NSTimeInterval)secsToBeAdded sinceDate:(NSDate

Page 135: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

135

*)anotherDate; (da NSDate)

• (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)aStyle

backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag; (da NSWindow)

• (id)initWithFrame:(NSRect)frameRect; (da NSControl e NSView)

Questi inizializzatori sono metodi il cui nome inizia con “init” e restituiscono un oggetto

di un tipo id dinamico, inoltre seguono le convenzioni Cocoa per i metodi multi-

argomento, spesso infatti usano WithType: o FromSource: prima del primo (e più

importante) argomento.

4.4.6.2.2 Possibili problemi con metodi init…

Anche se i metodi init... devono restituire un oggetto, non necessariamente però tale

oggetto è l'ultimo allocato (il ricevitore del messaggi di init). In sostanza è possibile che

l'oggetto restituito da un init... potrebbe non essere quello che si voleva inizializzare.

Due situazioni posso portare portare alla restituzione di un oggetto diverso da quello

allocato. La prima implica due situazioni, se deve esistere una istanza singleton oppure se

la definizione di un attributo di un oggetto deve essere univoca. Molte classi Cocoa, per

esempio NSWorkspace, abilitano un'unica istanza in un programma, una classe in tal caso

deve garantire che viene creata una sola istanza, restituendola se perviene un'ulteriore

richiesta di istanza.

Una situazione simile si verifica quando un oggetto richiede un attributo particolare per

essere unico. Ricordando l'esempio della classe Account, un oggetto di tale classe deve

avere un identificatore unico. Nel caso in cui l'inizializzatore, chiamato ad esempio

initWithAccountID: riceve in ingresso un identificatore che già è stato associato ad un altro

oggetto, possono verificarsi due ipotesi:

• Si rilascia l'oggetto appena allocato.

• Si restituisce l'oggetto account precedentemente inizializzato con quell'identificatore.

In questo modo l'inizializzatore si assicura l'unicità dell'identificatore fornendo al tempo

Page 136: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

136

stesso la risposta a ciò che gli era stato chiesto, un oggetto con un identificatore unico.

A volte un metodo init... non può realizzare una richiesta di inizializzazione. Ad esempio,

un metodo initFromFile: necessita per inizializzare un oggetto dal contenuto di un file di

un path come parametro di ingresso. Potrebbe però accadere che il path sia errato e

l'oggetto non può essere inizializzato.

Quando un metodo init... non può inizializzare un oggetto può proseguire in due modi

diversi:

• Rilascia l'oggetto appena allocato.

• Restituisce un valore nullo.

Restituire un valore nullo indica che l'oggetto non può essere creato, questo suggerisce che

generalmente bisogna controllare il valore restituito dall'inizializzatore prima di procedere

con il programma:

id anObject = [[MyClass alloc] init];

if (anObject) {

[anObject doSomething];

// more messages...

} else {

// handle error

}

Poiché un metodo init... potrebbe restituire un valore nullo o un oggetto diverso da quello

allocato, non è sicuro usare l'istanza restituita da alloc oppure allocWithZone: al posto di

quello restituito dall'inizializzatore. Si consideri il codice seguente:

Page 137: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

137

id myObject = [MyClass alloc];

[myObject init];

[myObject doSomething];

Riquadro 12: Oggetto restituito da init

Il metodo init nel Riquadro 12 potrebbe restituire un valore nullo oppure sostituire

l'oggetto con uno differente. Poiché è possibile inviare un messaggio nullo senza sollevare

un'eccezione non accadrebbe nulla nel primo caso, ma per evitare sostituzioni errate si

deve sempre fare affidamento sull'oggetto inizializzato invece dell'oggetto grezzo appena

allocato. È raccomandabile quindi costruire il messaggio di allocazione ed inizializzazione

e testare l'oggetto restituito prima di procedere con le successive operazioni.

id myObject = [[MyClass alloc] init];

if ( myObject ) {

[myObject doSomething];

} else {

// error recovery...

}

Appena inizializzato un oggetto non lo si dovrebbe inizializzare una seconda volta, spesso

questa operazione genera un'eccezione da parte del framework della classe dell'oggetto.

Ad esempio, la seconda inizializzazione nell'esempio che segue potrebbe generare

un'eccezione.

NSString *aStr = [[NSString alloc] initWithString:@"Foo"];

aStr = [aStr initWithString:@"Bar"];

Page 138: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

138

4.4.6.2.3 Costruire un inizializzatore

Ci sono diversi passaggi critici da seguire al momento di implementare un metodo init...

che serve come unico inizializzatore della classe:

• Deve sempre invocare per prima la superclasse di inizializzatori.

• Verificare l'oggetto restituito dalla superclasse. Se è un valore nullo allora

l'inizializzazione non deve procedere.

• Quando si inizializzano variabili riferite ad oggetti, bisogna trattenere una copia

dell'oggetto.

• Dopo aver impostato una variabile ai valori iniziali deve restituirla, a meno che:

o Non sia stato necessario restituire un oggetto che la sostituisce, in questo caso

bisogna rilasciare l'oggetto appena allocato.

o Un problema di inizializzazione impedisce il proseguimento, in questo caso deve

restituire un valore nullo.

Un metodo init... che applica i punti 2 e 3 appena illustrati è indicato nel Riquadro 13:

Page 139: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

139

- (id)initWithAccountID:(NSString *)identifier {

if ( self = [super init] ) {

Account *ac = [accountDictionary objectForKey:identifier];

if (ac) { // object with that ID already exists

[self release];

return [ac retain];

}

if (identifier) {

accountID = [identifier copy]; // accountID is

instance variable

[accountDictionary setObject:self forKey:identifier];

return self;

} else {

[self release];

return nil;

}

} else

return nil;

}

Riquadro 13: Inizializzatore

Non è necessario inizializzare tutte le variabili di un oggetto, ma giusto quelle necessarie

al suo funzionamento, in genere è sufficiente l'inizializzazione predefinita che imposta a

zero le variabili da inizializzare. Bisogna inoltre assicurarsi che vengano trattenute copie

delle variabili di istanza come richiesto da memory management.

L'obbligo di richiamare per primo l'inizializzatore della superclasse è importante, si deve

tener presente infatti che un oggetto ingloba non solo le istanze della sua classe, ma anche

quelle di tutte le classi della sua gerarchia. Ciò vuol dire che, invocando per primo

l'inizializzatore della superclasse si garantisce che vengano inizializzati tutti gli oggetti

ereditati, rispettando la catena gerarchica. La classe invoca l'inizializzazione della classe

da cui discende e così facendo si risale la catena come indicato nella Figura 20. Il rispetto

Page 140: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

140

dell'ordine è critico in quando il ritardo nell'inizializzazione dipende dal numero di

variabili che le superclassi hanno e dai valori a cui devono essere impostate.

La gerarchia degli inizializzatori è importante quando si crea una sottoclasse. A volte il

metodo init... della superclasse è sufficiente per inizializzare le istanze della sottoclasse.

Potrebbe però non essere così, quindi lo si dovrebbe sovrascrivere. Se non lo si

sovrascrive invece verrà invocata l'implementazione della superclasse e dato che la

superlcasse non conosce nulla della sottoclasse, le istanze potrebbero non essere

inizializzati correttamente.

Figura 19: Gerarchia di inizializzazione

Page 141: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

141

4.4.6.2.4 Inizializzatori multipli ed inizializzatori designati

Una classe può definire più di un inizializzatore, questi possono offrire la stessa

inizializzazione accettando però diversi tipi di input. La classe NSSet, per esempio,

fornisce diversi inizializzatori che accettano gli stessi dati ma in forme diverse, uno accetta

un oggetto NSArray, un altro una lista di contatori di elementi ed un altro una lista di

elementi che terminano con un valore nullo.

- (id)initWithArray:(NSArray *)array;

- (id)initWithObjects:(id *)objects count:(unsigned)count;

- (id)initWithObjects:(id)firstObj, ...;

Alcune sottoclassi trovano conveniente che gli inizializzatori forniscano valori predefiniti

ad un inizializzatore che prende la serie completa di tutti i parametri per l'inizializzazione.

Questo inizializzatore è generalmente l'inizializzatore detto designato ed è il più

importante della classe. Ad esempio, si consideri una classe Task che dichiara un

inizializzatore designato con la seguente dichiarazione:

- (id)initWithTitle:(NSString *)aTitle date:(NSDate *)aDate;

La classe Task potrebbe includere inizializzatori secondari che semplicemente invocano il

designato passandogli i valori di default per quei parametri che gli inizializzatori secondari

non hanno esplicitamente richiesto.

- (id)initWithTitle:(NSString *)aTitle {

return [self initWithTitle:aTitle date:[NSDate date]];

}

- (id)init {

return [self initWithTitle:@”Task”];

Page 142: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

142

}

Il designato gioca un ruolo importante per una classe, assicura infatti che le variabili

ereditate sono inizializzate invocando il designato della superclasse. Tipicamente è il

metodo init... che ha più argomenti in ingresso e che svolge la maggior parte del lavoro.

Inoltre è quello che gli inizializzatori secondari della classe invocano tramite messaggi.

Quando si definisce una sottoclasse si deve conoscere il designato della superclasse ed

invocarlo nel designato della sottoclasse attraverso un messaggio. Bisogna inoltre

assicurarsi che tutti gli inizializzatori ereditati sono collegati allo stesso modo. Quando si

definisce un inizializzatore di una classe bisogna quindi tener presente che tutti i designati

sono concatenati tra loro tramite messaggi alle superclassi e che tutti gli inizializzatori

sono collegati ai designati delle proprie classi attraverso messaggi.

Un esempio che può chiarire tale dinamica è il seguente:

Si considerino tre classi: A, B e C, ereditate una dall'altra. Ogni sottoclasse aggiunge una

variabile ed implementa un metodo init... (il designato) per inizializzare le proprie

variabili. Si definiscono inoltre inizializzatori secondari e si assicuri che gli inizializzatori

ereditati siano trascurati se necessario. La Figura 21 illustra gli inizializzatori delle tre

classi e le loro relazioni.

Page 143: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

143

Il designato di ogni classe è l'inizializzatore con maggiore copertura, il metodo che

inizializza gli attributi aggiunti dalla sottoclasse. Il designato è anche il metodo init... che

invoca tramite messaggio alla superclasse il suo metodo designato. Nell'esempio di Figura

21 il designato della classe C, initWithTitle:date:, invoca il designato della superclasse,

initWithTitle:, che a sua volta invoca il metodo init della classe A.

Gli inizializzatori secondari spesso trascurano le versioni di inizializzatori ereditate. La

Figura 20: Interazione tra inizializzatore designato e secondari

Page 144: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

144

classe C, nell'esempio di Figura 21, sovrascrive initWithTitle: ed invoca il suo designato

passandogli un valore predefinito. Questo designato, a sua volta, invoca il designato della

classe B, che è il metodo sovrascritto initWithTitle:. Se si invia un messaggio

initWithTitle: ad un oggetto della classe B e classe C, bisogna invocare diverse

implementazioni di metodi. D'altro canto, se la classe C non sovrascrive initWithTitle: e si

invia un messaggio ad un'istanza della classe C, l'implementazione della classe B

dovrebbe essere invocata. Conseguentemente l'istanza C verrebbe inizializzata in maniera

incompleta in quanto manca un dato. Quando si crea una sottoclasse quindi bisogna

assicurarsi che tutti i metodi di inizializzazione siano collegati nella catena gerarchica.

In sintensi quindi, a volte il designato di una superclasse è sufficiente per la sottoclasse e

così risulta superfluo implementarne un altro. Altre volte invece il designato di una classe

deve ampliare le caratteristiche del designato della classe da cui deriva, così deve

sovrascriverlo.

4.4.6.3 I metodi dealloc e finalize

Nelle classi Cocoa che utilizzano garbage collection, il metodo finalize è il posto dove la

classe dispone di tutte le risorse rimanenti e degli allegati delle sue istanze prima che

queste vengano liberate. Nelle classi Cocoa che usano una gestione tradizionale della

memoria, il metodo comparabile per liberare le risorse è il metodo dealloc. Sebbene siano

simili ci sono differenze significative tra di essi.

Da molti punti di vista il metodo dealloc può essere considerato la controparte del metodo

init... della classe, in particolare del suo designato. Tale metodo è invocato esattamente

prima della distruzione dell'oggetto, garantendo che le istanze dell'oggetto vengano

rilasciate e che la memoria allocata dinamicamente venga liberata.

Il punto finale del parallelismo tra il metodo dealloc ed init... ha a che fare con

l'invocazione dell'implementazione dello stesso metodo della superclasse. Un

inizializzatore invoca il designato della superclasse come primo passo, dealloc invece

Page 145: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

145

invoca il dealloc della superclasse solo alla fine. Di conseguenza la deallocazione

funziona in maniera simmetrica rispetto ai metodi init....

- (void)dealloc {

[accountDictionary release];

if ( mallocdChunk != NULL )

free(mallocdChunk);

[super dealloc];

}

Riquadro 14: Esempio di metodo dealloc

Bisogna notare, come nell'esempio del Riquadro 14, che è prudente verificare se la

variabile malloc è non-nulla prima di liberarla. Poiché non crea problemi inviare un

messaggio nullo ad un oggetto, questa precauzione non è necessaria per le istanze di

variabili.

Simile al metodo dealloc, il metodo finalize chiude le risorse utilizzate da un oggetto in un

ambiente garbage collection prima che un oggetto venga liberato e la sua memoria resa

disponibile. Come in dealloc l'ultima riga di un'implementazione di finalize dovrebbe

invocare l'implementazione del metodo della superclasse. Tuttavia, a differenza del

metodo dealloc, un'implementazione finalize non deve rilasciare le istanze di variabili

perchè garbage collection distrugge questi oggetti a tempo debito.

Ci sono comunque differenze significative tra questi metodi di “pulizia”. È

raccomandabile non implementare un metodo finalize e, se necessario, riferirlo a pochi

oggetti. Il primo motivo per non consigliare l'uso del finalize è che l'ordine in cui gli

oggetti garbage-collected sono inviati al finalize è indeterminato, anche se ci sono

collegamenti tra loro. Una conseguenza potenzialmente negativa di questa

indeterminazione è nel caso in cui stanno circolando messaggi tra gli oggetti che stanno

per essere “finalizzati”. Il codice infatti non può dipendere dagli effetti collaterali derivanti

Page 146: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

146

dall'ordine di deallocazione degli oggetti. Bisognerebbe quindi costruire un codice nel

quale la liberazione di blocchi, la chiusura del descrittore di file e l'annullamento della

registrazione di osservatori avviene prima che sia invocato il metodo finalize.

4.4.6.4 Metodi costruttori di classe

Questi metodi combinano l'allocazione e l'inizializzazione in un unico blocco e

restituiscono un oggetto autorilasciato (in codice memory managed). Questi metodi sono

nella forma “+ (type)className...” dove className esclude ogni prefisso.

Cocoa fornisce diversi esempi, NSDate include il seguente metodo costruttore:

+ (id)dateWithTimeIntervalSinceNow:(NSTimeInterval)secs;

+

(id)dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)secs;

+ (id)dateWithTimeIntervalSince1970:(NSTimeInterval)secs;

I metodi costruttori possono essere più di una semplice comodità perchè non solo possono

combinare allocazione ed inizializzazione, ma la prima può comunicare con la seconda.

Questo vuol dire che si potrebbe allocare memoria per esempio solo dopo che il processo

di inizializzazione ha verificato di quanta memoria si necessita.

Si consideri per esempio di dover inizializzare un oggetto collection da un file che codifica

un numero qualsiasi di elementi per collection (oggetti NSString, NSData, NSNumber e

così via). Prima che il metodo costruttore possa conoscere quanta memoria deve allocare

per la collezione, deve leggere prima il file ed analizzare la lista di proprietà per poi

determinare quanti elementi ci sono e di che tipo di oggetti si tratta. Un altro scopo per

l'utilizzo di metodi costruttori è garantire che una determinata classe offra una istanza

singleton. Anche se un metodo init... potrebbe verificare che esista solo un'istanza in

qualunque momento del programma, potrebbe però richiedere di allocare un' istanza

“grezza” che poi eventualmente verrà rilasciata se un'altra è già attiva. Un metodo

Page 147: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

147

costruttore invece evita l'allocazione di un oggetto senza la certezza di doverlo

inizializzare. Nel Riquadro 15 è indicato un metodo costruttore per una istanza singleton.

static AccountManager *DefaultManager = nil;

+ (AccountManager *)defaultManager {

if (!DefaultManager) DefaultManager = [[self

allocWithZone:NULL] init];

return DefaultManager;

}

Riquadro 15: Un metodo costruttore per una istanza singleton

4.4.7 Introspection

Introspection è una caratteristica molto potente di ambienti e linguaggi orientati agli

oggetti. Questa caratteristica si riferisce alla capacità di un oggetto di divulgare

informazioni su sé stessi nella fase di runtime. Tali dettagli riguardano il posto nella catena

gerarchica, la conformità a determinati protocolli e le risposte a determinati messaggi. Il

protocollo e la classe NSObject definiscono molti metodi introspection che si possono

usare al tempo di esecuzione per caratterizzare gli oggetti.

4.4.7.1 Valutazione dei rapporti gerarchici

Per conoscere qualcosa di un oggetto, bisogna innanzitutto conoscere la classe a cui

appartiene, inoltre potrebbe servire conoscere le sue caratteristiche, gli attributi che

rappresenta ed a quali tipi di messaggi può rispondere. Attraverso l'introspection quindi si

acquisisce familiarità con la classe dell'oggetto e si conosce per esempio quali messaggi

non bisogna inviargli.

Il protocollo NSObject fornisce diversi metodi per determinare la posizione di un oggetto

nella gerarchia delle classi, tale metodo opera a diversi livelli di granularità. I metodi di

istanza class e superclass per esempio, restituiscono oggetti Class che rappresentano

rispettivamente la classe e la superclasse per il ricevitore. Questi metodi richiedono di

Page 148: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

148

confrontare un oggetto Class con un altro. Il Riquadro 16 è un esempio descrittivo.

// ...

while ( id anObject = [objectEnumerator nextObject] ) {

if ( [self class] == [anObject superclass] ) {

// do something appropriate...

}

}

Riquadro 16: Utilizzo di metodi di class

A volte si utilizzano i metodi class e superclass per ottenere un ricevitore appropriato ad

una classe di messaggi.

Per verificare la classe di appartenenza di un oggetto bisogna inviargli un messaggio

isKindOfClass: oppure isMemberOfClass:. Il primo metodo restituisce conferma o meno

se il ricevitore è un'istanza di una determinata classe o di una classe da essa derivata. Un

messaggio isMemberOfClass:, d'altro canto, restituisce conferma se il ricevitore è

un'istanza di una specifica classe. Il metodo isKindOfClass: è generalmente più utilizzato,

in quanto da esso si può ricavare in una sola volta la gamma completa di messaggi da

poter inviare ad un oggetto. Si consideri il seguente frammento di codice:

if ([item isKindOfClass:[NSData class]]) {

const unsigned char *bytes = [item bytes];

unsigned int length = [item length];

// ...

}

Sapendo che l'oggetto item deriva dalla classe NSData, Il codice successivo sa di poter

inviare NSData byte ed il messaggio lenght. La differenza tra isKindOfClass: e

Page 149: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

149

isMemberOfClass: diventa evidente se si assume che item è un'istanza di NSMutableData.

Se si usa isMemberOfClass: al posto di isKindOfClass:, il codice nel blocco non verrà mai

eseguito perchè item non è un'istanza di NSData ma di NSMutableData:, una sua

sottoclasse.

4.4.7.2 Implementazione di metodi e conformità ai protocolli

Due metodi introspection importanti di NSObject sono respondsToSelector: e

conformToProtocol:. Questi metodi restituiscono rispettivamente se un oggetto

implementa un determinato metodo oppure un oggetto è conforme ad un determinato

protocollo formale.

È possibile utilizzare questi metodi in situazioni simili. Consentono di scoprire se alcuni

oggetti anonimi potenzialmente rispondono adeguatamente ad un particolare messaggio o

una serie di messaggi, prima di inviargliene qualcuno. In questo modo sarà possibile

evitare eccezioni di runtime derivanti da selettori non riconosciuti. Application Kit

fornisce protocolli informali per verificare se i delegati attuano un metodo delegato

(utilizzando respondsToSelector:) prima del ricorso a tale metodo.

4.4.7.3 Comparazione di oggetti

Anche se non sono metodi strettamente introspection i metodi hash e isEqual: compiono

operazioni simili. Tali metodi sono indispensabili agli strumenti di runtime per identificare

e comparare oggetti, ma invece di interrogare il sistema di runtime per ricevere

informazioni sugli oggetti, si basano su comparazione logica tra classi specifiche.

I metodi hash ed isEqual:, dichiarati entrambi dal protocollo NSObject sono strettamente

connessi. Il metodo hash deve essere implementato per restituire un intero che può essere

usato come indirizzo di una tabella per una tabella hash strutturata. Se due oggetti sono

uguali (come determinato dal metodo isEqual:) devono avere lo stesso valore hash.

Il metodo isEqual: è estremamente semplice, confronta il ricevitore con l'oggetto passato

come argomento. La comparazione di oggetti spesso informa il sistema runtime sulle

Page 150: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

150

decisioni da prendere e cosa si può fare con un oggetto, nel Riquadro 17 si usa isEqual:

per decidere che azione compiere.

- (void)saveDefaults {

NSDictionary *prefs = [self preferences];

if (![origValues isEqual:prefs])

[Preferences savePreferencesToDefaults:prefs];

}

Riquadro 17: Uso di isEqual

Se si sta creando una sottoclasse, potrebbe essere necessario sostituire isEqual: per

aggiungere ulteriori controlli sull'uguaglianza di oggetti. La sottoclasse potrebbe definire

infatti ulteriori attributi che potrebbero assumere lo stesso valore in due istanze diverse, in

modo tale da poter essere considerate uguali.

4.4.8 Oggetti modificabili

Gli oggetti Cocoa possono essere mutabili o immutabili. Non è possibile modificare i

valori incapsulati in oggetti immutabili, quando un tale oggetto viene creato il suo valore

rimane lo stesso per tutto il suo ciclo di vita. È possibile altresì cambiare il valore

incapsulato in un oggetto mutabile in qualunque momento.

Le impostazioni predefinite degli oggetti prevedono che questi siano mutabili. Molti

oggetti permettono di cambiare i loro valori incapsulati attraverso metodi accessori setter.

Per esempio è possibile cambiare le dimensioni, la posizione, il titolo ed altre

caratteristiche degli oggetti NSWindows.

Il framework Foundation aggiunge altre caratteristiche introducendo il concetto di classi

che hanno varianti mutabili e non mutabili. Le sottoclassi mutabili sono generalmente

sottoclassi di classi immutabili ed hanno il prefisso Mutable nel loro nome. Esempi di

queste classi possono essere NSMutableArray, NSMutableDictionary, NSMutableSet,

NSMutableURLRequest, NSMutableString ed altre.

Page 151: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

151

Salvo per NSMutableParagraphStyle in Application Kit, il framework Foundation

definisce sempre nel nome tutte le classi mutabili, ma in generale tutti i framework Cocoa

possono potenzialmente avere varianti mutabili o immutabili delle classi.

La necessità di avere la possibilità di rendere un oggetto immutabile risiede nel fatto che

rendere sempre un oggetto mutabile potrebbe portare a diversi problemi di coerenza di

dati. Ad esempio, nel caso in cui un utente stia visualizzando una matrice che popola una

tabella, se viene selezionata una riga di tale matrice potrebbe darsi che un'altra parte del

codice nel frattempo abbia modificato quei valori o quei riferimenti. Una tale situazione

genererebbe un problema nella visualizzazione di quei dati. Avere oggetti immutabili

quindi garantisce che un oggetto non cambi il suo valore in maniera inaspettata mentre lo

si sta usando.

Gli oggetti che si prestano a diventare immutabili sono gli oggetti che includono collezioni

di valori discreti o contengono valori registrati in buffer. Non tutti i valori comunque

beneficiano nell'avere una versione mutabile, un valore ad esempio che contiene un

singolo dato come una istanza di NSNumber o NSDate non è un buon candidato per essere

mutabile. Quando uno di questi valori cambia, ha molto più senso sostituire l'istanza con

una nuova piuttosto che cambiare il valore contenuto nell'attributo.

Le prestazioni sono un altro motivo per gestire versioni immutabili di oggetti come

collezioni e dizionari. tali oggetti, se mutabili, devono gestire dinamicamente il cambio di

locazione di memoria, la quantità di memoria da allocare e deallocare, quindi un oggetto

mutabile può risultare meno efficiente della sua controparte immutabile.

In teoria un oggetto immutabile garantisce che i suoi valori rimangano stabili, in pratica

però questa caratteristica non è sempre verificata. Un metodo può scegliere un oggetto

mutabile come tipo restituito da una sua variante immutabile, successivamente, potrebbe

decidere di modificare tale oggetto, eventualmente violando le assunzioni e le scelte fatte

dal destinatario sulla base del valore originario. Da tali considerazioni sono deducibili

alcuni approcci alla programmazione che ottimizzano l'utilizzo di oggetti mutabili. Ad

Page 152: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

152

esempio è consigliabile utilizzare varianti mutabili di oggetti quando questi necessitano di

frequenti modifiche. Allo stesso tempo è consigliabile sostituire un oggetto immutabile

piuttosto che gestirne uno mutabile, se questo non richiede modifiche frequenti.

È da segnalare inoltre che molte classi mutabili offrono metodi costruttori ed

inizializzatori che permettono di specificare la probabile capacità iniziale dell'oggetto,

questo approccio rende più efficiente la memorizzazione di oggetti mutabili. È inoltre

possibile creare un oggetto mutabile creando una copia di un oggetto esistente dello stesso

tipo generale. Per fare ciò, bisogna invocare il metodo mutableCopy, implementato da

ogni superclasse immutabile di una classe mutabile di Foundation. É possibile inoltre

inviare una copia di un oggetto mutabile per creare una copia immutabile dello stesso.

In generale le domande da porsi nella scelta se utilizzare oggetti mutabili o immutabili

riguarda la natura delle variabili, se sono stringhe di caratteri, dizionari o oggetti che non

variano frequentemente nel tempo. Generalmente quando si ha un oggetto il cui contenuto

cambia in blocco è utile crearlo immutabile, Stringhe (NSString) ed oggetti di dati

(NSData) generalmente fanno parte di questa categoria. Altresì, se un oggetto si modifica

continuamente è giusto crearlo mutabile. Collezioni come array e dizionari fanno parte di

questa categoria, tuttavia la frequenza dei cambiamenti e le dimensioni della collezione

dovrebbe essere un fattore decisionale. Per esempio se si dispone di un oggetto che cambia

di rado è meglio renderlo immutabile.

Un'ulteriore considerazione da sottolineare riguarda il salvataggio di oggetti mutabili nelle

collezioni. Tali oggetti potrebbero infatti creare problemi, alcune collezioni potrebbero

essere invalidate o corrotte se gli oggetti contenuti mutano, in quanto la mutazione

potrebbe influire sul modo in cui tali oggetti sono inseriti nella collezione. Considerando

ad esempio oggetti NSDirectory e NSSet, la corruzione potrebbe riguardare la proprietà

delle chiavi hash. Se si modificano gli oggetti per esempio potrebbero influenzare il

risultato del valore hash o del metodo isEqual: e la collezione risulterebbe corrotta. Un

altro esempio potrebbe riguardare una collezione ordinata, come un array. Se cambiano le

Page 153: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

153

sue proprietà, tale ordinamento potrebbe non essere più valido.

4.4.9 Raggruppamento di classi

Il raggruppamento di classi (detta anche Class cluster) è uno strumento che estende l'uso

del framework Foundation. Lo scopo che persegue è di raggruppare un certo numero di

sottoclassi, private e concrete sotto una superclasse pubblica e astratta. Tale

raggruppamento delle classi semplifica l'architettura pubblica visibile di un framework

orientato agli oggetti senza ridurne le potenzialità.

4.4.9.1 Struttura gerarchica

Per illustrare l'architettura dei raggruppamenti e dei suoi benefici, consideriamo il

problema di costruire una gerarchia che definisce gli oggetti che registrano numeri di

differenti tipologie (char, int, float, double). Poiché i numeri di diversi tipi hanno molte

caratteristiche in comune (per esempio possono essere convertiti da un tipo in un altro e

possono essere rappresentati da una stringa), possono essere osservati in una singola

classe. Comunque l'archiviazione di tali oggetti è differente, di conseguenza non è

efficiente rappresentarli con una sola classe. È possibile quindi considerare la seguente

architettura:

Number è la superclasse astratta che dichiara nei suoi metodi le operazioni comuni alle sue

sottoclassi, comunque non dichiara istanze di variabili per memorizzare numeri. Le

sottoclassi dichiarano tali variabili e condividono l'interfaccia di programmazione

Figura 21: Class Cluster

Page 154: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

154

dichiarata da Number.

Possiamo quindi dedurre che gli utenti di questa gerarchia vedano solo una classe pubblica

ed astratta, Number. Il modo in cui è possibile istanziare oggetti dipende da come la classe

astratta gestisce le istanze.

4.4.9.2 Creare istanze

La superclasse astratta deve dichiarare metodi per creare istanze delle sue sottoclassi

private. È responsabilità della superclasse dispensare un oggetto della propria sottoclasse

basato su un metodo invocato. Non è possibile e non si deve scegliere la classe

dell'istanza.

Nel framework Foundation generalmente è possibile creare un oggetto invocandolo con

metodo di classe + className... o metodi init... e alloc....

Considerando la classe NSNumber come esempio, è possibile inviare i seguenti messaggi

per creare oggetti number:

NSNumber *aChar = [NSNumber numberWithChar:’a’];

NSNumber *anInt = [NSNumber numberWithInt:1];

NSNumber *aFloat = [NSNumber numberWithFloat:1.0];

NSNumber *aDouble = [NSNumber numberWithDouble:1.0];

In questo modo si creano oggetti che si deallocheranno automaticamente.

Ogni oggetto restituito (aChar, anInt, aFloat e aDouble) può appartenere a differenti

sottoclassi. Anche se la classe dell'oggetto è nascosta, la sua interfaccia è pubblica e viene

dall'interfaccia dichiarata dalla classe astratta NSNumber. Anche se non è propriamente

corretto conviene considerare gi oggetti aChar, anInt, aFloat, e aDouble come istanze

della classe NSNumber, da quando sono creati ed usati dai metodi della classe NSNumber.

4.4.9.3 Raggruppamento di classi con molteplici superclassi pubbliche

Nell'esempio del paragrafo 4.4.9.2. Una classe astratta e pubblica dichiara l'interfaccia per

Page 155: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

155

molteplici sottoclassi private, questo è un esempio puro di raggruppamento di classi. È

inoltre possibile e spesso molto utile, avere due o più classi astratte pubbliche che

dichiarano l'interfaccia del raggruppamento. Questo è evidente nel Framework

Foundation, che include questi raggruppamenti:

Raggruppamento

di classi

Superclassi pubbliche

NSData NSData

NSMutableData

NSArray NSArray

NSMutableArray

NSDictionary NSDictionary

NSMutableDicotionary

NSString NSString

NSMutabileString

Tabella 3: Raggruppamenti di classi

Esistono comunque altri raggruppamenti di tipi, ma quelli in tabella 3 illustrano come

cooperano nella dichiarazione dell'interfaccia di programmazione di un raggruppamento di

classi. In ognuno di questi raggruppamenti, un nodo pubblico dichiara metodi ai quali

possono rispondere tutti gli oggetti, l'altro nodo dichiara metodi che sono appropriati solo

per gruppi di oggetti che possono far modificare il proprio contenuto.

Questo tipo di costruzione delle interfacce permette di rendere l'interfaccia di

programmazione di un framework molto più espressiva. Ad esempio si consideri un

oggetto Book che dichiara questo metodo:

- (NSString *)title;

Page 156: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

156

L'oggetto Book potrebbe restituire sia una sua istanza che creare una nuova stringa. È

chiaro però da questa dichiarazione che la stringa restituita non può essere modificata

senza generare un warning dal compilatore.

Page 157: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

157

Capitolo 5 Presentazione di un caso di studio Il seguente capitolo descrive eat&Phone, un software sviluppato all'occorrenza come caso

di studio. Tale applicazione risalta le caratteristiche hardware integrate nel dispositivo

mobile, utilizzando gli strumenti di sviluppo messi a disposizione da Apple inc. In

particolare ci si è concentrati sull'utilizzo del GPS16 e della possibilità di interagire con il

web attraverso il browser Safari.

I requisiti di tale software richiedono infatti di poter determinare le coordinate

geografiche. Una volta determinate tali coordinate è richiesto al software di interagire con

un sito web, navigabile in Safari, per determinare i ristoranti in prossimità della locazione

determinata.

I requisiti esposti permettono in un primo momento di interagire con il Core locatio per

determinare le coordinate geografiche; successivamente con le altre applicazioni istallate

nel dispositivo, in particolare con il Browser Safari.

Bisogna notare inoltre, che tutti gli strumenti messi a disposizione da Apple permettono di

costruire interfacce utente in modo facile e sopratutto conservando quelle caratteristiche di

usabilità tipiche delle applicazioni per Mac OS X ed iPhone OS. È interesse della casa

produttrice quindi riutilizzare, anche nelle applicazioni di terze parti, quelle caratteristiche

estetiche e di usabilità che permettano all'utente di riconoscere determinate funzioni

proprio perchè comuni a tutte le applicazioni dell'ambiente di utilizzo.

5.1 Progettazione

Il paradigma di progettazione delle applicazioni per iPhone segue una struttura di tre

elementi principali: Model, controller e View. Il collegamento tra questi elementi è

indicato nella Figura 23.

16 Si noti che il GPS integrato non è l'unico modo per ricavare le coordinate geografiche. Il dispositivo infatti le ricava

anche dalla triangolazione delle celle e dal collegamento internet, a differenti livelli di precisione.

Page 158: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

158

In tale struttura quindi è il controller che gestisce la comunicazione tra la base di dati e le

View dell'interfaccia utente. Nel seguito verrà descritto come questo approccio è stato

applicato nel software utilizzato come caso d'uso.

Per realizzare eat&Phone è stato necessario far riferimento al framework Location, tale

software infatti utilizza la classe CLLocationManager per determinare la posizione

geografica. Nei capitoli precedenti si è visto come Apple fornisca un ambiente di sviluppo

integrato nel quale è possibile sviluppare l'applicazione. Per lo sviluppo di eat&Phone si è

utilizzato Xcode 3.1, Interface Builder 3.1.2 ed iPhone Simulator 2.1.

Le classi implementate in eat&Phone sono le seguenti:

• MainViewController, la cui superclasse è UIViewController. Tale classe adotta il

protocollo MyCLControllerDelegate dichiarato in MyCLController.h

• eat&PhoneAppDelegate, la cui superclasse è NSObject. Tale classe adotta il protocollo

UIApplicationDelegate della classe UIApplication del framework UIKit.

• MyCLController, la cui superclasse è NSObject. Tale classe adotta il protocollo

Figura 22: Paradigma di progettazione

Page 159: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

159

CLLocationManagerDelegate dichiarato in CLLocationManagerDelegate.h, del

framework Core Location.

Considerando il paradigma di programmazione che fa riferimento allo schema Model-

Control-View è possibile considerare la classe MainViewController come fusione tra il

Model ed il Control. Tale costruzione viene dal fatto che il Model rappresenta la struttura

dati da cui prelevare le informazioni per inviarle all'interfaccia grafica

(MainWindows.xib). Nel caso in esame invece non esiste un vera e propria struttura dati,

ma una comunicazione attraverso messaggi tra le classi implementate ed il Core Location.

La classe che fa da Controller è MainViewController, che utilizza il protocollo

MyCLControllerDelegate per comunicare con MyCLController. MainViewcontroller è

infatti il suo delegato. MyCLController invece è il delegato di Core Location, riceve

aggiornamenti sulle coordinate geografiche attraverso il protocollo adottato

CLLocationManagerDelegate. MainViewController, ricevuti gli aggiornamenti sulle

coordinate e sulla stringa da inviare a Safari, aggiorna l'interfaccia grafica.

La classe MainViewController oltre a mostrare sul display la posizione gps, verifica la

disponibilità del LocationService usando la proprietà locationServicesEnabled della classe

CLLocationManager.

Il diagramma delle classi è rappresentato nella seguente figura:

Page 160: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

160

Di seguito sono descritte le classi implementate:

Nome: MainViewController

Gestisce l'interfaccia principale nella quale si visualizzano i dati ricavati

dal GPS ed i pulsanti di avvio della ricerca delle coordinate e di

collegamento al browser. È inoltre il delegato di MyCLController e quindi

riceve da esso gli agigornamenti

Attributi dichiarati nell'interfaccia:

Figura 23: Diagramma delle Classi

Page 161: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

161

<updateTextView>:<IBOutlet UITextView>

<startStopButton>:<IBOutlet UIBarButtonItem>

<launchBrowser>:<IBOutlet UIBarButtonItem>

<spinner>:<IBOutlet UIActivityIndicatorView>

<isCurrentlyUpdating>:<BOOL>

Metodi dichiarati nell'interfaccia:

<startStopButtonPressed>:<IBAction>

<launchButtonPressed>:<IBAction>

Protocolli adottati:

MyCLControllerDelegate

Nome: eatPhoneAppDelegate

Delegato dell'applicazione, crea la finestra dell'applicazione e la View

principale.

Attributi dichiarati nell'interfaccia:

<window>:<IBOutlet UIWindow>

<mainViewController>:<IBOutlet MainViewController>

Protocolli adottati:

UIApplicationDelegate

Nome:MyCLControllerDelegate

Classe Singleton delegato per ricevere da CoreLocation le coordinate.

Attributi dichiarati nell'interfaccia:

<locationManager>:<CLLocationManager>

<delegate>:<id>

<locURL>:<NSMutableString>

Protocolli dichiarati nell'interfaccia:

Page 162: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

162

<MyCLControllerDelegate>:<NSObject>

Metodi dichiarati nell'interfaccia:

- (void)locationManager:(CLLocationManager *)manager

didUpdateToLocation:(CLLocation *)newLocation

fromLocation:(CLLocation *)oldLocation

- (void)locationManager:(CLLocationManager *)manager

didFailWithError:(NSError *)error;

+ (MyCLController *)sharedInstance;

Protocolli adottati:

CLLocationManagerDelegate

Come descritto nei capitoli precedenti Objective-C è un linguaggio estremamente basato

sullo scambio di messaggi. Le informazioni scambiate tra le classi transitano quindi

attraverso messaggi. Il flusso di tali informazioni avviene nel seguente modo:

• Il delegato dell'applicazione (eat&PhoneAppDelegate) crea una finestra ed inizializza

un oggetto MainViewController.

• MainViewController attende input dall'utente fino a che non lo riceve tramite il tasto

StartStopButton.

• Tale input invoca MCLController attraverso il protocollo

CLLocationManagerDelegate.

• MCLController, delegato del Core Location, restituisce il risultato a

MainViewController che lo invia alla view dell'interfaccia grafica.

• Una volta ricevuto l'aggiornamento dal Core Location attraverso MCLController,

MainViewController è pronto a ricevere anche un altro input tramite il tasto “Trova

Ristorante” (launchButtonPressed), in modo da inviare un stringa come URL al

Browser Safari.

• L'applicazione si chiude automaticamente nel momento in cui si avvia il Browser.

Page 163: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

163

È possibile osservare il Collaboration Diagram delle classi nella seguente figura:

5.2 Implementazione

Per implementare eat&Phone si è utilizzato come base la funzione main generata

automaticamente da Xcode per le applicazioni Cocoa. L'ambiente di sviluppo infatti, nel

momento in cui si crea un nuovo progetto, costruisce una funzione main elementare con

una interfaccia grafica vuota. Tale procedura permette di avere già un'applicazione

eseguibile, pur non avendo ancora implementato nessuna caratteristica.

Si analizzino ora le implementazioni delle singole classi.

5.2.1 eat&PhoneAppDelegate

L'interfaccia di eat&PhoneAppDelegate è contenuta nel file eat&PhoneAppDelegate.h.

Nella sua dichiarazione viene richiamata la classe MainViewController in quanto dichiara

una variabile di istanza MainViewController. Il richiamo avviene attraverso la direttiva:

Figura 24: Collaboration Diagram

Page 164: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

164

@class MainViewController;

Nell'interfaccia inoltre viene dichiarata l'adozione del protocollo UIApplicationDelegate.

Tale protocollo dichiara metodi implementati dal delegato dell'oggetto singelton

UIApplication. Implementando questi metodi, il delegato può rispondere al lancio ed alla

chiusura dell'applicazione, ai warning di memoria insufficiente, all'apertura di risorse URL

ed altri eventi di sistema.

L'implementazione di tale classe è realizzata nel file eat&PhoneAppDelegate.m. Viene

implementato al suo interno il solo metodo opzionale applicationDidFinishLaunching:

- (void)applicationDidFinishLaunching:(UIApplication *)application

{

[window addSubview:[mainViewController view]];

[window makeKeyAndVisible];

Tale metodo, dichiarato nella classe UIApplication.h, indica al delegato quando

l'applicazione ha terminato l'avvio. È utilizzato in genere per inizializzare attraverso il

delegato la configurazione iniziale dell'applicazione, crea la finestra principale ed un

oggetto mainViewController. È utile per ripristinare l'applicazione allo stato precedente,

invia inoltre una notifica UIApplicationDidFinishLaunchingNotification contestualmente

alla chiamata di tale metodo.

5.2.2 MainViewController

MainViewController dichiara la propria interfaccia in MainViewController.h. All'interno

di questa, adotta il protocollo MyCLControllerDelegate, con il quale riceve aggiornamenti

da MyCLController. Tale protocollo è dichiarato nell'interfaccia di MyCLController. Le

Page 165: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

165

istanze di variabili implementate sono quindi gli elementi della View, l'interfaccia grafica

creata con Interface Builder. Nello specifico sono dichiarati:

• updateTextView. Il campo di testo da aggiornare attraverso il protocollo

MyCLControllerDelegate

• startStopButton. il tasto che avvia la comunicazione con MyCLController per

ricercare le coordinate GPS

• launchBrowser. il tasto che avvia il browser Safari, inviandogli la stringa come URL

da aprire

• spinner. Indica l'avvio della ricerca delle coordinate geografiche

Inoltre è dichiarata una variabile booleana che indica se si sta effettuando una ricerca o

meno. Tale variabile serve per disabilitare il tasto di lancio del Browser.

I metodi pubblici dichiarati sono quelli relativi alla pressione del tasto startStopButton e

del tasto di lancio del Browser.

La dichiarazione dell'interfaccia è la seguente:

#import "MyCLController.h"

@interface MainViewController : UIViewController

<MyCLControllerDelegate> {

IBOutlet UITextView *updateTextView;

IBOutlet UIBarButtonItem *startStopButton;

IBOutlet UIBarButtonItem *launchBrowser;

IBOutlet UIActivityIndicatorView *spinner;

BOOL isCurrentlyUpdating;

}

Page 166: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

166

//permettono di attribuire proprietà di non atomicità

// e di ratain alle variabili di istanza dichiate.

@property (nonatomic, retain) UITextView *updateTextView;

@property (nonatomic, retain) UIBarButtonItem *startStopButton;

@property (nonatomic, retain) UIBarButtonItem *launchBrowser;

@property (nonatomic, retain) UIActivityIndicatorView *spinner;

- (IBAction)startStopButtonPressed:(id)sender;

- (IBAction)launchButtonPressed:(id)sender;

@end

L'implementazione di tale classe è strutturata in MainViewController.m. Innanzitutto

vengono attribuiti i metodi accessori alle variabili di istanza attraverso la direttiva

@synthesize. Successivamente si implementa il primo e fondamentale metodo,

initWithNibName.

// Il primo metodo implementato, inizializza l'applicazione

- (id)initWithNibName:(NSString *)nibNameOrNil

bundle:(NSBundle*)nibBundleOrNil {

if (self = [super initWithNibName:nibNameOrNil

bundle:nibBundleOrNil]) {

isCurrentlyUpdating = NO;

[launchBrowser setEnabled:NO];

}

return self;

}

Page 167: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

167

Tale metodo è fondamentale in quanto restituisce l'oggetto ViewController inizializzato

con il nib file17 del progetto. I parametri di tale metodo di istanza sono:

• nibName. È il nome del nib file senza informazioni del path di origine. Per definire

particolari valori del nib file è necessario sovrascrivere il metodo viewDidLoad

(descritto di seguito).

• NibBundle. È il path di riferimento per il nib file del progetto che si sta implementando.

Il parametro restituito da initWithNibName è quindi un oggetto UIViewController

inizializzato.

Il metodo viewDidLoad è invece sovrascritto nel seguente modo:

// è invocato solo quando la view è caricata per la prima

volta

- (void)viewDidLoad {

[startStopButton

setTitle:NSLocalizedString(@"StartButton", @"Start")];

//crea una istanza MyCLController e si attribuisce la sua

delega.

[MyCLController sharedInstance].delegate = self;

//verifica se l'utente ha disabilitato i location services,

nel qual

//caso disabilita il tasto start e visualizza un messaggio

nella view

17 La descrizione del Nib File è al paragrafo “Interface Builder” 3.2.4

Page 168: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

168

if ( ! [MyCLController

sharedInstance].locationManager.locationServicesEnabled ) {

[self addTextToLog:NSLocalizedString(@"NoLocationServices",

@"User disabled location services")];

startStopButton.enabled = NO;

}

}

Riquadro 4: Metodo ViewDidLoad

Tale metodo void è implementato dalla classe UIViewController ed è invocato

immediatamente dopo il caricamento della view. Al suo interno si inizializza un oggetto

MyCLController attraverso il metodo di classe sharedInstance, implementato in

MyCLController.m. Tale metodo restituisce una istanza Singleton. Inoltre, attraverso il

messaggio “delegate = self”, MainViewController si dichiara come delegato per

l'istanza appena creata. All'interno di tale metodo si effettua anche il controllo

sull'eventuale disabilitazione da parte dell'utente dei location services.

Il metodo pubblico che riguarda l'azione relativa al tasto startStopButton è la seguente:

// Invocato alla pressione del tasto Start

-(IBAction)startStopButtonPressed:(id)sender {

if (isCurrentlyUpdating) {

[[MyCLController sharedInstance].locationManager

stopUpdatingLocation];

isCurrentlyUpdating = NO;

[startStopButton

Page 169: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

169

setTitle:NSLocalizedString(@"StartButton", @"Start")];

[spinner stopAnimating];

[launchBrowser setEnabled:YES];

} else {

[launchBrowser setEnabled:NO];

[[MyCLController

sharedInstance].locationManagerstartUpdatingLocation];

isCurrentlyUpdating = YES;

[startStopButton

setTitle:NSLocalizedString(@"StopButton", @"Stop")];

[spinner startAnimating];

}

}

Il metodo startStopButtonPressed restituisce un valore di tipo IBAction. Tale valore viene

usato da Interface Builder per sincronizzare le azioni implementate nel codice con la sua

lista interna di azioni. Tale metodo verifica innanzitutto se è in corso una ricerca di

coordinate GPS attraverso la variabile booleana isCurrentlyUpdating. Nel caso verifica

questa condizione abilita attraverso il tasto startStopButton l'interruzione della ricerca,

altrimenti l'avvia attraverso lo stesso tasto.

I principali metodi richiamati in startStopButtonPressed sono i seguenti:

• stopUpdatingLocation. Metodo della classe CLLocationManager.h del framework

Core Location. È invocato alla pressione del tasto startStopButton, durante la ricerca

delle coordinate GPS.

Page 170: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

170

• startUpdatingLocation. Metodo della classe CLLocationManager.h del framework

Core Location. È invocato alla pressione del tasto startStopButton, per avviare la

ricerca di coordinate GPS.

• StartAnimating. Metodo della classe UIActivityIndicatorView ereditata da UIView nel

framework UIKit. È invocato tramite messaggio per l'animazione dell'oggetto spinner,

serve ad indicare che una ricerca di coordinate è in corso.

• StopAnimating. Metodo della classe UIActivityIndicatorView ereditata da UIView nel

framework UIKit. È invocato tramite messaggio per l'interruzione dell'animazione

dell'oggetto spinner.

Il metodo che invece lancia il browser attraverso l'azione legata al tasto LaunchButton è il

seguente:

// invocato alla pressione del tasto di ricerca del ristorante

-(IBAction)launchButtonPressed:(id)sender {

if ((!isCurrentlyUpdating)) {

[[UIApplication sharedApplication] openURL:[NSURL

URLWithString:[MyCLController sharedInstance].locURL]];

}

}

Tale metodo prima verifica se si sta effettuando una ricerca di coordinate, nel qual caso

inibisce la l'azione di lancio del Browser. Se invece la ricerca è finita e le coordinate GPS

sono state ricavate allora viene attivato il tasto launchBrowser.

All'interno del metodo si invia una stringa a Safari che contiene il link da aprire. Questa

operazione avviene attraverso messaggi innestati descritti di seguito:

Page 171: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

171

• Si crea una istanza singleton della classe UIApplication (del framework UIKit)

attraverso il metodo sharedApplication

• si invoca il metodo openURL: sempre di UIApplication. Tale metodo accetta in

ingresso l'url creato a sua volta da URLWithString:, della classe NSURL del framework

Foundation. Tale metodo converte in url una stringa che gli viene passata come

parametro. La stringa utilizzata è locURL, ricavata dall'istanza singelton

MyCLController.

Si noti che il metodo openURL: apre l'applicazione predefinita dal sistema per aprire un

url. Inoltre tale metodo genera la chiusura dell'applicazione che lo richiama, nel caso in

esame di eat&Phone.

Nel seguito dell'implementazione della classe sono implementati i metodi privati

trasparenti all'utente ed i metodi delegati per la classe MyCLController:

• shouldAutorotateToInterfaceOrientation:. Tale metodo è dichiarato nella classe

UIViewController. Restituisce un valore booleano che indica quando il view controller

ruota automaticamente la view.

• didReceiveMemoryWarning. Tale metodo è dichiarato nella classe

UIApplicationDelegate. È un metodo opzionale e void, comunica al delegato quando

l'applicazione riceve dal sistema un warning per memoria insufficiente.

5.2.3 MyCLController

MyCLController è una classe singleton usata per comunicare con il framework Core

Location ed inviare gli aggiornamenti alla View, attraverso MainViewController.

L'interfaccia di MyCLController è dichiarata all'interno del file MyCLController.h,

implementata come nel Riquadro seguente:

// Questo protocollo è usato per inviare il testo ala View

// che contiene gli aggiornanti sulle coordinate GPS

Page 172: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

172

@protocol MyCLControllerDelegate <NSObject>

@required

-(void)newLocationUpdate:(NSString *)text;

-(void)newError:(NSString *)text;

@end

// Definizione della classe

@interface MyCLController : NSObject <CLLocationManagerDelegate>

{

CLLocationManager *locationManager;

id delegate;

NSMutableString *locURL;

}

@property (nonatomic, retain) CLLocationManager *locationManager;

@property (nonatomic, assign) id <MyCLControllerDelegate>

delegate;

@property (nonatomic, retain) NSMutableString *locURL;

- (void)locationManager:(CLLocationManager *)manager

didUpdateToLocation:(CLLocation *)newLocation

fromLocation:(CLLocation *)oldLocation;

- (void)locationManager:(CLLocationManager *)manager

didFailWithError:(NSError *)error;

Page 173: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

173

+ (MyCLController *)sharedInstance;

@end

Si noti che la prima dichiarazione riguarda il protocollo MyCLControllerDelegate. Tale

protocollo, come si è detto, permette la comunicazione a MainViewController degli

aggiornamenti sulle coordinate GPS ricevute da Core Location. Prevede

l'implementazione di due metodi obbligatori:

• newLocationUpdate. Necessario al passaggio della stringa di testo da inviare alla view

• newError. Per comunicare a MainViewController eventuali errori.

L'interfaccia della classe invece dichiara la superclasse (NSObject) e la conformità al

protocollo opzionale CLLocationManagerDelegate. Tale protocollo fa parte del

framework Core Location ed è dichiarata in CLLocationManagerDelegate.h.

CLLocationManagerDelegate definisce i metodi usati per ricevere aggiornamenti sulla

locazione da un oggetto CLLocationManager. Tra le variabili di istanze quindi è

inizializzata una istanza CLLocationManager.

Sono inizializzate inoltre un oggetto generico id ed una stringa (locURL), che verrà

utilizzata per passare a Safari l'indirizzo URL da aprire.

In conclusione vengono dichiarati due metodi di istanza pubblici (per la gestione delle

coordinate GPS e per la gestione di errori) ed un metodo di classe, per l'inizializzazione di

una istanza singleton (richiamato da MainViewController).

L'implementazione di questa classe è descritta in MyCLController.m. In tale file, prima

dell'implementazione della classe, viene dichiarata una istanza singleton MyCLController,

inizializzata al valore nullo. Tale istanza è necessaria all'implementazione del metodo di

classe sharedistance. La sua dichiarazione è:

Page 174: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

174

static MyCLController *sharedCLDelegate = nil;

Il primo metodo implementato nella classe è il metodo init:

- (id) init {

self = [super init];

if (self != nil) {

self.locationManager = [[[CLLocationManager alloc]

init] autorelease];

// Comunica al location manager di inviare aggiornamenti a

questo oggetto

self.locationManager.delegate = self;

self.locURL = [[[NSMutableString alloc] init] autorelease];

}

return self;

}

Come si può notare la prima operazione invoca il metodo init per la superclasse, nel caso

non restituisca valore nullo procede nel seguente modo:

• alloca ed inizializza un oggetto CLLocationManager, lo associa così alla variabile

locationManager.

• Si definisce delegato di locationManager, così da ricevere gli aggiornamenti da core

location sulla posizione GPS.

Page 175: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

175

• Alloca ed inizializza una stringa LocURL di tipo mutabile.

La seconda implementazione riguarda il metodo pubblico che aggiorna le coordinate GPS

ed il timestamp. La sua prima parte è descritta nel seguente Riquadro:

- (void)locationManager:(CLLocationManager *)manager

didUpdateToLocation:(CLLocation *)newLocation

fromLocation:(CLLocation *)oldLocation

{

NSMutableString *update = [[[NSMutableString alloc] init]

autorelease];

// Timestamp

NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc]

init] autorelease];

[dateFormatter setDateStyle:NSDateFormatterMediumStyle];

[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];

[update appendFormat:@"%@\n\n", [dateFormatter

stringFromDate:newLocation.timestamp]];

Per definire il timestamp il metodo innanzitutto alloca ed inizializza una variabile della

classe NSDateFormatter, dateFormatter. Dopo avergli attribuito la formattazione

MediumStyle a data ed orario invia una sequenza di messaggi innestati, per:

• prelevare attraverso il metodo timestamp (di CLLocation) la data e l'orario usandoli

come attributi del metodo stringFromDate. Ottenendo una stringa data.

• Associate alla variabile update tale stringa gli si aggiungono successivamente i caratteri

Page 176: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

176

speciali per inviare il testo a capo18 (\n\n).

Tale metodo prosegue con la ricerca delle coordinate GPS nel seguente modo:

// Coordinate orizzontali

if (signbit(newLocation.horizontalAccuracy)) {

// accuratezza negatvo indica un errore di rilevazone

//o misure non calcolabili

[update appendString:LocStr(@"LatLongUnavailable")];

} else {

// CoreLocation restituisce valori positivi per North & East,

negativi

// per South e West

// si costruisce la stringa inviandogli 4 argomenti

[update appendFormat:LocStr(@"LatLongFormat"),

fabs(newLocation.coordinate.latitude),

signbit(newLocation.coordinate.latitude) ?

LocStr(@"Sud") : LocStr(@"Nord"),

fabs(newLocation.coordinate.longitude),

signbit(newLocation.coordinate.longitude) ?

LocStr(@"Ovest") : LocStr(@"Est")];

[update appendString:@"\n"];

[update

appendFormat:LocStr(@"MeterAccuracyFormat"),

newLocation.horizontalAccuracy];

18 I caratteri aggiunti in coda servono, una volta inviata la stringa alla View, per distanziare il testo del timestamp dalle

coordinate geografiche.

Page 177: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

177

Innanzitutto viene verificato che le coordinate siano attendibili. La verifica avviene

attraverso il segno delle coordinate orizzontali. HorizontalAccuracy è dichiarato in

CLLocation.h, se negativo indica che la latitudine e la longitudine delle coordinate sono

errate. Se dovesse verificare un errore verrebbe restituito alla View la stringa

corrispondente a LatLogUnvailable19. Se invece dovesse risultare corretto il segno di

horizontalAccuracy, si aggiunge in coda alla variabile update la stringa creata

successivamente. Tale stringa viene costruita attraverso coordinate, che racchiude

informazioni sulle coordinate geografiche. Attraverso LocStr quindi si aggiungono ad

update informazioni sui punti cardinali e sull'accuratezza estrapolata da

horizontalAccuracy. In tal modo update contiene informazioni sul time stamp, le

informazioni geografiche e di precisione nella rilevazione.

Il Riquadro seguente invece utilizza le stesse procedure per formattare la stringa dell'URL

da inviare a Safari.

//URLCord ristampa le coordinate nel modo in cui vengono salvate

prima //dell'elaborazione e costruisce la stringa che deve essere

inviata come url a Safari.

[self.locURL appendFormat:LocStr(@"UrlString"),

fabs(newLocation.coordinate.latitude),

signbit(newLocation.coordinate.latitude) ?

LocStr(@"S+log=") : LocStr(@"N+long="),

19 Tale stringa è dichiarata nel file Localizable.strings e è richiamata dalla variabile LocStr. Tale variabile è stata

definita in MyCLController.m con la sintassi: #define LocStr(key) [[NSBundle mainBundle]

localizedStringForKey:(key) value:@"" table:nil].

Page 178: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

178

fabs(newLocation.coordinate.longitude),

signbit(newLocation.coordinate.longitude) ?

LocStr(@"O") : LocStr(@"E")];

}

[update appendString:@"\n\n"];

// Invia gli aggiornamenti al delegato che nel caso in

esame è

//MainViewController

[self.delegate newLocationUpdate:update];

}

L'ultima operazione del metodo invia due messaggi innestati. Il primo invia update alla

variabile newLocationUpdate, questa poi viene inviata al proprio delegato:

MainViewController.

L'implementazione del metodo di classe dichiarato nell'interfaccia è la seguente:

// crea una istanza singleton

+ (MyCLController *)sharedInstance {

@synchronized(self) {

if (sharedCLDelegate == nil) {

[[self alloc] init]; // l'assegnazione non è

fatta qui

}

Page 179: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

179

}

return sharedCLDelegate;

}

Tale metodo di classe restituisce sharedCLDelegate, una istanza singleton. In sostanza si

assicura dell'unicità dell'oggetto MyCLController.

5.3 Snapshot dell'applicazione

In figura 26 è visualizzata l'icona dell'iPhone sul display del simulatore.

Page 180: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

180

Figura 25: Icona di eat&Phone sul simulatore

Page 181: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

181

In Figura 27 è presente l'interfaccia di eat&Phone al suo lancio.

Figura 26: lancio di eat&Phone

Page 182: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

182

In Figura 28 eat&Phone ha ricavato le coordinate geografiche.

Figura 27: Visualizzazione delle coordinate geografiche

Page 183: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

183

L'ultima immagine, Figura 29, visualizza invece i dati ottenuti e visualizzati in Safari.

Figura 28: Visualizzazione dei dati in Safari

Page 184: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

184

Conclusioni Nei capitoli affrontati nel presente lavoro di tesi, si è analizzata la piattaforma software

iPhone, il dispositivo mobile promosso da casa Apple. Dopo un primo confronto

dell'approccio commerciale offerto per l'iPhone rispetto a prodotti concorrenti, ci si è

soffermati sulle sue caratteristiche principali. In particolare si è approfondita la struttura

del sistema operativo e dei framework implementati. L'analisi dei framework inoltre, come

per il sistema operativo, è stata effettuata in comparazione con quelli implementati nel

sistema Mac OS X 10.5, quindi nella sua ultima versione. Il sistema operativo desktop è

infatti la piattaforma da cui deriva. Le semplificazioni apportate riguardano ad esempio gli

strumenti di gestione della memoria per le applicazioni, per esigenze prestazionali iPhone

OS non supporta Garbage Collection. Inoltre è stato alleggerito di tutti i driver relativi a

periferiche esterne ed all'accesso da riga di comando, tipico di un ambiente BSD. Tale

analisi ha evidenziato inoltre come la Apple renda l'ambiente Cocoa estremamente

integrato agli strumenti di sviluppo che offre ed alle caratteristiche principali dell' iPhone

stesso. La filosofia “Apple“ infatti si riflette in ogni suo prodotto. La casa produttrice

orienta gli sviluppatori a porre l'attenzione più sull'interfaccia grafica da offrire all'utente

che alla stesura di codice. Anche nella documentazione è infatti consigliato l'uso degli

strumenti di sviluppo da loro distribuiti e delle interfacce grafiche offerte dei framework.

Tale approccio di coerenza grafica tra tutti i software della piattaforma restituisce

familiarità all'utente che li utilizza, punto di forza dei prodotti Apple.

I framework implementati infatti permettono di accedere a tutte le funzionalità del

dispositivo, ma anche di usufruire in maniera immediata e semplice delle caratteristiche

funzionali che hanno reso famoso l'iPhone. Tali framework infatti implementano ad

esempio le animazioni per la ricerca in elenchi o la gestione delle fotografie. Sono proprio

tali animazioni, estremamente curate nei dettagli, che permettono in poco tempo di

costruire un'applicazione accattivante ed usabile, coerente con tutte le altre applicazioni. È

importante notare che l'iPhone non gode di tutte le caratteristiche hardware di altri

Page 185: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

185

dispositivi mobili concorrenti, in quanto ad esempio non può registrare filmanti o inviare

MMS, la sua stessa fotocamera ha una risoluzione molto inferiore rispetto ad altri

dispositivi. Nonostante ciò è uno dei prodotti più ricercati. Tale successo è dovuto proprio

alla grande usabilità che offre, rendendolo realmente un oggetto con cui poter navigare in

rete, riprodurre un video o scorrere le foto in maniera estremamente agevole. Insieme poi

ad un elegante design è comprensibile il successo di mercato.

Altra notazione importante riguarda gli strumenti di sviluppo e le applicazioni che la

Apple offre per ottimizzare i software sviluppati. Xcode è un ambiente di sviluppo che

ingloba caratteristiche comuni ad altri ambienti comparabili, come il completamento

automatico del testo o la divisione di un progetto in cartelle di gestione dei file. Quello che

lo caratterizza è invece l'integrazione con Interface Builder per generare interfacce di

utente e con i software per l'ottimizzazione delle prestazioni.

Essendo l'iPhone un dispositivo mobile, le sue caratteristiche hardware sono ridotte e

quindi bisogna ottimizzare per esempio l'uso della memoria e la gestione dell'allocazione

di oggetti nelle applicazioni. A causa di tali limitazioni, sull'iPhone non è possibile la

gestione della memoria Garbage Collection realizzabile su Mac OS X, bisogna quindi

gestire in maniera più semplice gli oggetti allocati e deallocati. La ridotta capacità

hardware però rende questa gestione estremamente delicata, come in tutti i dispositivi

mobili. Nello sviluppo di un'applicazione infatti bisogna tenere conto degli errori di

allocazione di memoria perchè generano rallentamenti ed invecchiamento del software

stesso. Se tali problemi in un sistema desktop sono spesso trascurabili, in un sistema

mobile non lo sono. Apple offre uno strumento semplice per verificare la correttezza di

codice nell'allocazione di oggetti, monitorando l'esecuzione del programma sviluppato. È

infatti noto che riscontrare in fase di debug tali problemi è estremamente complicato. Ad

esempio, attraverso tali software, si è potuto verificare agevolmente la correttezza del caso

di studio implementato nell'ultimo capitolo. Non sono stati riscontrati infatti oggetti

allocati in un primo momento e non deallocati successivamente.

Page 186: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

186

Altro strumento di supporto è iPhone Simulator. Tale software permette di testare

l'applicazione prima di procedere alla sua distribuzione. Bisogna notare che se non si

accede al programma di sviluppo iPhone e quindi non si paga la quota annua prevista, non

si può testare l'applicazione su nessun dispositivo. Tale limitazione non è trascurabile, in

quanto il simulatore non è del tutto attendibile. Se risulta sufficiente per applicazioni

semplici, lo stesso non si può dire per applicazioni più articolate. Bisogna infatti

sottolineare che tale simulatore non permette di verificare le prestazioni del software in

maniera attendibile in quanto i programmi vanno in esecuzione sull'hardware del desktop

sul quale si sviluppa, estremamente più efficiente di quello del dispositivo. Inoltre nel

simulatore non è possibile testare applicazioni che prevedono caratteristiche essenziali,

come il cambio di orientamento da orizzontale a verticale del dispositivo. Non è inoltre

possibile simulare in alcun modo eventi multitouch. Tale limitazione rende quindi

vincolante per il test definitivo di un'applicazione l'adesione al programma Apple,

vincolando ancor più sviluppatori di terze parti al “mondo” Apple. Tale approccio infatti è

riscontrabile in tutte le fasi di sviluppo e pubblicazione del software. Per poter anche

scaricare l'SDK è necessario registrarsi al programma di sviluppo, anche se questa volta in

maniera gratuita. Per poter invece pubblicare un software, anche solo gratuitamente,

bisogna ottenere la vidimazione della Apple. È possibile quindi notare un secondo vincolo.

Oltre al test finale che risulta di fatto a pagamento (necessario tra l'altro per la diffusione

dell'applicazione), si è sottoposti al vincolo di vidimazione, rischiando di vanificare così

gli investimenti nello sviluppo. Il terzo vincolo posto dalla casa produttrice è che l'unico

canale di distribuzione delle applicazioni è lo store on line, gestito sempre dalla Apple.

La Apple in sostanza mantiene il completo controllo del codice della piattaforma, degli

strumenti di sviluppo distribuiti ed allo stesso tempo del software pubblicato sulla

piattaforma da essa stessa gestita. Se da un lato questa “filosofia” commerciale ha sempre

contraddistinto Apple, dall'altro bisogna notare come altri soggetti del settore abbiano

scelto approcci in direzione decisamente contraria. Come si è evidenziato nel primo

Page 187: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

187

capitolo, il mercato del software per i dispositivi mobili sta investendo molto

nell'approccio collaborativo e nella distribuzione di software sotto licenze sempre meno

restrittive. L'ultima osservazione degna di nota riguarda il linguaggio Objective-C analizzato.

Nonostante sia possibile sviluppare in Xcode con diversi linguaggi, Objective-C rimane il

principale soggetto. Tale linguaggio appare decisamente dinamico e semplice da utilizzare.

Bisogna comunque sottolineare che la documentazione distribuita è esclusivamente in

inglese, non prevede quindi alcun tipo di localizzazione e sopratutto non è reperibile

facilmente in forma cartacea. Inoltre è da notare l'enorme supporto che la Apple offre su

Objective-C agli sviluppatori. Tale documentazione non è però all'altezza della fama

Apple, in quanto le sezioni on line risultano ostiche e di difficile interpretazione.

Probabilmente meno materiale ma più curato sarebbe stato ottimale. Altre documentazioni

ottenute nelle ricerche in internet invece sono risultate di ottima qualità, alcune di queste

erano documenti distribuiti da Apple sotto forma di file Pdf. La documentazione offerta

comunque riguarda quasi esclusivamente framework, strumenti e linguaggio di sviluppo,

scarsa invece è quel che riguarda il sistema operativo nei sui strati più bassi.

Page 188: Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente … · L'iPhone è un prodotto orientato al mercato consumer, non ha quindi un target di tipo business. I suoi punti

Strumenti e linguaggi per lo sviluppo di applicazioni in ambiente iPhone OS

188

Bibliografia Alfieri, V. (2006). Implementazione di un servizio Voip in ambiente SOA per mobile computing. Apple. (s.d.). Introduction to Cocoa Fundamental Guide. Tratto da Developer Connection: http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals Apple. (s.d.). The Cocoa Environment. Tratto da Developer Connection: http://developer.apple.com/Cocoa/Conceptual/CocoaFundamentals Apple. (s.d.). The development Environment. Tratto da http://developer.apple.com/Cocoa/Conceptual/CocoaFundamentals Apple. (2006). The Objective-C 2.0 Programming Language. Ascione, P. (2005). Progetto ed implementazione di un Data Collector per Sistemi Operativi Symbian. Cesare, M. D. (2007). Il sistema Operativo Mac OS X.