Movatterモバイル変換


[0]ホーム

URL:


Vai al contenuto
WikipediaL'enciclopedia libera
Ricerca

Objective-C

Da Wikipedia, l'enciclopedia libera.
Objective-C
linguaggio di programmazione
AutoreBrad Cox eTom Love (Stepstone Corp.)
Data di origine1984
Ultima versione2.0
Utilizzolinguaggio general-purpose
Paradigmiprogrammazione orientata agli oggetti, programmazione multi-paradigma, class-based programming eriflessione
Tipizzazionedebole,dinamica
Estensioni comunih, m, mm e C
Influenzato daC eSmalltalk
Ha influenzatoC++,Swift,Java
Implementazione di riferimento
Sistema operativoMultipiattaforma
Sito webdeveloper.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html
Modifica dati su Wikidata ·Manuale

Objective-C (in breveObj-C) è unlinguaggio di programmazioneriflessivoorientato agli oggetti, sviluppato daBrad Cox alla metà deglianni ottanta presso laStepstone Corporation.

Come lo stesso nome suggerisce, l'Objective-C è un'estensione a oggetti dellinguaggio C. Esso mantiene lacompleta compatibilità col C (a differenza di quanto avviene, per esempio, nel caso delC++). Tra l'altro, anche a causa di questa compatibilità, Objective-C non è dotato diforte tipizzazione (caratteristica che invece esibiscono, tra gli altri, sia C++ cheJava).

Le estensioni a oggetti con cui Objective-C arricchisce il modello semantico del C sono ispirate al linguaggioSmalltalk, in particolar modo allagestione dei messaggi. Le caratteristiche delruntime system collocano l'Objective-C tra i linguaggi ad oggetti dinamici. Sono supportati tutti gli elementi classici della programmazione a oggetti; ma non mancano concetti innovativi anche su questo fronte, come il meccanismo dellecategorie e strumenti legati allariflessione.

La sua diffusione è principalmente legata alframeworkOpenStep diNeXT e al suo successoreCocoa, presente nel sistema operativomacOS diApple. ANeXT si deve il supporto dell'Objective-C nel compilatoregcc diGNU.

Storia

[modifica |modifica wikitesto]

Nei primianni ottanta, la pratica comune dell'ingegneria del software era basata sullaprogrammazione strutturata. Questa modalità era stata sviluppata per poter suddividere programmi di grandi dimensioni in parti più piccole, principalmente per facilitare il lavoro di sviluppo e di manutenzione del software. Ciononostante, col crescere della dimensione dei problemi da risolvere, la programmazione strutturata divenne sempre meno utile, dato che conduceva alla stesura di un numero sempre maggiore di procedure, ad unospaghetti code e ad uno scarso riuso delcodice sorgente.

Venne ipotizzato poi che laprogrammazione orientata agli oggetti potesse essere una potenziale soluzione al problema. In effettiSmalltalk aveva già affrontato molte di queste questioni ingegneristiche, pur con lo svantaggio di necessitare di unamacchina virtuale che interpretava unoggetto in memoria chiamato immagine contenente tutti gli strumenti necessari. L'immagine Smalltalk era molto grossa, usava tendenzialmente un'enorme quantità di memoria per l'epoca e girava molto lentamente anche per la mancanza di un supporto specifico dell'hardware alle macchine virtuali.

L'Objective C fu creato principalmente daBrad Cox eTom Love all'inizio deglianni ottanta allaStepstone. Entrambi erano stati introdotti a Smalltalk durante la loro permanenza al Programming Technology Center dellaITT Corporation nel1981. Cox aveva iniziato ad interessarsi ai problemi legati alla riusabilità del software e si accorse che un linguaggio simile a Smalltalk sarebbe stato estremamente valido per costruire potentiambienti di sviluppo per i progettisti di ITT. Cox iniziò così a modificare il compilatore C per aggiungere alcune delle caratteristiche di Smalltalk. Ottenne così ben presto una implementazione funzionante di una estensione ad oggetti del linguaggio C che chiamòOOPC (Object-Oriented Programming in C). Nel frattempo Love fu assunto da Schlumberger Research nel1982 ed ebbe l'opportunità di acquisire la prima copia commerciale di Smalltalk-80 che influenzò in seguito lo sviluppo della loro creatura.

Per dimostrare che il linguaggio costituiva un reale progresso, Cox mostrò che per realizzare componenti software intercambiabili erano necessari pochi adattamenti pratici agli strumenti già esistenti. Nello specifico, era necessario supportare gli oggetti in modo flessibile con un insieme dilibrerie software che fossero usabili e consentissero al codice sorgente (e ad ogni risorsa necessaria al codice) di essereraccolto in un solo formatomultipiattaforma.

Cox e Love formarono infine una nuovaimpresa, la Productivity Products International (PPI), per commercializzare il loro prodotto che accoppiava un compilatore Objective C con una potente classe di librerie.

Nel1986 Cox pubblicò la sua descrizione dell'Objective C nella sua forma originale nel libroObject-Oriented Programming, An Evolutionary Approach. Sebbene fosse attento a puntualizzare che la questione della riusabilità del software non poteva essere esaurita dallinguaggio di programmazione, l'Objective C si trovò spesso ad essere confrontato, caratteristica per caratteristica, con gli altri linguaggi.

Nel1988,NeXT, la compagnia fondata daSteve Jobs dopoApple, ottenne la licenza dell'Objective C da Stepstone (allora proprietaria delmarchio) e realizzò il proprio compilatore Objective C e le librerie sulle quali basò l'interfaccia utente diNeXTSTEP. Sebbene leworkstation NeXTSTEP non riuscirono ad avere un forte impatto sul mercato, i loro strumenti vennero ampiamente apprezzati dall'industria del settore. Ciò portò NeXT ad abbandonare la produzione di hardware ed a focalizzarsi sugli strumenti software, vendendo NeXTSTEP (eOpenStep) come piattaforma per la programmazione.

In seguito ilprogetto GNU iniziò a lavorare sul clone libero che chiamòGNUstep, basato sullostandard OpenStep.Dennis Glatting scrisse il primorun-time gnu-objc nel1992 eRichard Stallman lo seguì subito dopo con un secondo. Il run-time GNU Objective C, che è usato dal1993, è stato sviluppato daKresten Krab Thorup mentre era studente universitario inDanimarca.

Dopo aver acquisito NeXT nel1996, Apple ha usato OpenStep come base per il suo nuovosistema operativomacOS. Questo le consentì di includere l'Objective C di NeXT ed il suo sistema di sviluppoProject Builder (in seguito rinominatoXcode). La maggior parte delle attualiAPI di Apple (API Cocoa) sono basate sugli oggetti d'interfaccia di OpenStep e costituiscono il più significativo ambiente di sviluppo basato su Objective C attualmente usato.

Sviluppi

[modifica |modifica wikitesto]

Oggi Objective C è spesso usato in tandem con librerie fisse di oggetti standard (spesso denominati "kit" o "framework") comeCocoa oGNUstep. Queste librerie sono spesso fornite assieme alsistema operativo: le librerie GNUstep sono parte della collezione di software GNU e a volte presenti in alcune distribuzioni Gnu/Linux e Cocoa diMacOS. Il programmatore non è obbligato ad ereditare le funzionalità della classe base esistente (NSObject). Objective C permette la dichiarazione di nuove classi base che non ereditino nessuna delle funzionalità preesistenti. Originariamente gli ambienti di programmazione basati su Objective C offrivano la classe Object con alcune funzionalità di base, ma con l'introduzione diOpenStep,NeXT ha creato una nuova classe base chiamata NSObject che offriva caratteristiche aggiuntive oltre a quelle di Object. Quasi tutte le classi di Cocoa ereditano da NSObject.

La rinominazione non è servita solo per differenziare i nuovi comportamenti delle classi nel nuovo framework, ma ha consentito al codice che ancora usava la classe Object di coesistere (sebbene con alcune limitazioni) nello stessorun-time system. Nello stesso tempo l'introduzione del prefisso di due lettere è diventato una sorta di surrogato alla mancanza in Objective C degli spacename (o Namespaces che dir si voglia). Usare un prefisso per creare un identificatore di package informale è diventata un'abitudine standard nella comunità di programmatori Objective C.

Objective C 2.0

[modifica |modifica wikitesto]

AllaWorldwide Developers Conference del2006,Apple ha annunciato l'uscita di "Objective C 2.0" i cui contenuti sono lagarbage collection, migliorie nella sintassi[1], miglioramenti delle prestazioni del run-time[2] e il supporto ai64-bit[3]. Non è ancora noto quando queste evoluzioni saranno supportate nel run-time GNU, sebbene lo siano già inMac OS X Leopard[4].

Garbage collection

[modifica |modifica wikitesto]

Objective C 2.0 consente lagarbage collection, ma in maniera dipendente dal sistema operativo. Tuttavia è possibile usarla in modo retro-compatibile, in modo che ilcodice sorgente scritto per versioni precedenti continui a funzionare.

Mentre precedentemente le variabili d'istanza richiedevano metodi espliciti di lettura e scrittura (dettigetters esetters), Objective C 2.0 introduce le proprietà (property) con la seguente sintassi:

@interfacePersona:NSObject{}@property(readonly)NSString*nome;@property(readonly)inteta;-(id)initWithName:(NSString)nomeeta:(int)eta;@end

Una volta inserite nell'interfaccia, si può accedere alle proprietà usando la notazione descritta nell'esempio:

NSString*nome=unaPersona.nome;

Il compilatore traduce questa notazione in chiamate di metodi accessori. L'istruzione precedente è equivalente a:

NSString*nome=[unaPersonanome];

Enumerazione veloce

[modifica |modifica wikitesto]

Invece di usare un oggetto enumeratore per operare iterazioni all'interno di una raccolta di oggetti, Objective C 2.0 offre una sintassi di ciclo dedicata; riprendendo l'esempio precedente:

for(Persona*personainlaGente)NSLog(@"%@ ha %i anni.",persona.nome,persona.eta);

Portable Object Compiler

[modifica |modifica wikitesto]

Oltre alle implementazioniGCC/NeXT/Apple, che hanno aggiunto diverse estensioni a quella originale diStepstone, esiste un'altra implementazioneOpen Source di Objective C che aggiunge un set di estensioni lievemente differente: ilPortable Object Compiler[5] implementa tra l'altro anche dei blocchi di codice sullo stile Smalltalk.

Sintassi

[modifica |modifica wikitesto]

L'Objective C è un sottile strato postosopra illinguaggio C; C quindi è unsottoinsieme stretto dell'Objective C. Ne consegue che è possibile compilare un qualsiasi programma scritto in C con un compilatore Objective C. La gran parte dellasintassi (clausole delpreprocessore,espressioni,dichiarazioni e chiamate di funzioni) è derivata da quella del C, mentre la sintassi relativa alle caratteristicheobject-oriented è stata creata per ottenere lacomunicazione a scambio di messaggi simile a quella diSmalltalk.

La sintassi aggiunta rispetto al C è intesa al supporto della programmazione ad oggetti. Il modello di programmazione dell'Objective C è basato sullo scambio di messaggi tra oggetti così come avviene inSmalltalk. Tale modello è differente da quello diSimula, che viene usato in numerosi linguaggi quali, tra gli altri, ilC++. Questa distinzione èsemanticamente importante e consiste principalmente nel fatto che in Objective C non sichiama unmetodo, ma siinvia unmessaggio.

Si dice che un oggetto chiamatoogg la cuiclasse implementa il metodofaiQualcosa,risponde al messaggiofaiQualcosa. L'invio del messaggiofaiQualcosa all'oggettoogg è espresso da:

[oggfaiQualcosa];

mentre l'azione equivalente in C++ e Java sarebbe espressa da:

ogg.faiQualcosa();

In questo modo è possibile inviare messaggi ad un oggetto anche se l'oggettonon è capace di rispondere. Questo differisce dai linguaggitipizzati staticamente come C++ eJava nei quali tutte le chiamate devono essere di metodi predefiniti.

Interfacce e implementazioni

[modifica |modifica wikitesto]

L'Objective C richiede che l'interfaccia e l'implementazione di una classe siano dichiarati in blocchi di codice differenti. Per convenzione l'interfaccia è messa in un file con suffisso ".h", mentre l'implementazione in un file con suffisso ".m".

L'interfaccia di una classe è solitamente definita in un file ".h". La convenzione usata è quella di assegnare il nome al file basandosi sul nome della classe, nell'esempio "NomeDellaClasse.h".

//definizione dell'interfaccia: "NomeDellaClasse.h"#import "NomeDellaSuperclasse.h"@interfaceNomeDellaClasse :NomeDellaSuperclasse{//variabili d'istanzaintvariabileIntera;floatvariabileFloat;...}//metodi di classe+metodoDiClasse1+metodoDiClasse2+...//metodi di istanza-metodoDiIstanza1-metodoDiIstanza2-...@end

Il segno meno (-) denota i metodi d'istanza, mentre il segno più (+) quello di classe (analoghi alle funzioni statiche del C++). Si noti la differenza di significato con le convenzioni deidiagrammi UML dove i due segni rappresentano rispettivamente i metodi privati e pubblici.

Implementazione

[modifica |modifica wikitesto]

L'interfaccia dichiara solamente iprototipi dei metodi e non i metodi stessi che vengono inseriti nell'implementazione. L'implementazione è solitamente scritta in un file con estensione ".m".La convenzione usata è quella di assegnare il nome al file basandosi sul nome della classe, nell'esempio "NomeDellaClasse.m"

//definizione dell'implementazione: "NomeDellaClasse.m"#import "NomeDellaClasse.h"@implementationNomeDellaClasse+metodoDiClasse1{// implementazione...}+metodoDiClasse2{// implementazione...}...-metodoDiIstanza1{// implementazione...}-metodoDiIstanza2{// implementazione...}...@end

I metodi sono scritti in maniera diversa dallefunzioni in stile C. Ad esempio, una funzione, sia in C che in Objective C segue la seguente forma generale:

intfai_la_radice_quadrata(inti){returnradice_quadrata(i);}

che avrà come prototipo:

intfai_la_radice_quadrata(int);

L'implementazione come metodo diverrà:

-(int)fai_la_radice_quadrata:(int)i{return[selfradice_quadrata:i];}

Un approccio più canonico alla scrittura del metodo sarebbe quello di citare il primo argomento nel nome del selettore:

-(int)faiLaRadiceQuadrataDiInt:(int)i{return[selfradiceQuadrataDiInt:i];}

Questa sintassi può apparire complicata, ma consente di assegnare i nomi aiparametri, ad esempio:

-(int)changeColorWithRed:(int)rgreen:(int)gblue:(int)b

può essere invocato così:

[myColorchangeColorWithRed:5green:2blue:6];

Le rappresentazioni interne di questi metodi possono variare con le diverse implementazioni di Objective C.

SemyColor, nell'esempio precedente, fosse della classeColor, internamente il metodo d'istanza-changeColorWithRed:green:blue: potrebbe essere etichettato_i_Color_changeColorWithRed_green_blue, dovei seguito dal nome della classe, si riferisce al fatto che è un metodo d'istanza ed i due punti (:) sono sostituiti daltrattino basso (_). Dato che l'ordine dei parametri fa parte del nome del metodo, esso non può essere cambiato.

In ogni caso i nomi interni delle funzioni sono usati raramente in maniera diretta e generalmente anche i messaggi inviati sono convertiti in funzioni definite in librerie dirun-time e non accedono direttamente ai nomi interni. Ciò è dovuto anche al fatto che al momento dellacompilazione non sempre si conosce quale metodo sarà effettivamente chiamato, perché la classe del destinatario (l'oggetto a cui viene inviato il messaggio) potrebbe essere sconosciuta fino al run-time.

Objective C è stato esteso daNeXT per introdurre il concetto diereditarietà multipla di specifica, ma non di implementazione, attraverso l'uso dei protocolli. Questo è unpattern ottenibile sia mediante una forma di ereditarietà multipla da unaclasse astratta (come in C++), sia (come più comunemente in Java oC#) mediante l'uso di un'interfaccia (anche in c++ ci sono le interfacce, anche se non esiste una keyword esplicita per dichiararle). Objective C fa uso di entrambi i protocolli, chiamatiprotocolli informali e di protocolli imposti dal compilatore dettiprotocolli formali.

Un protocollo informale è una lista dimetodi che possono essere implementati da una classe. Viene specificato nella documentazione, dato che non è presente esplicitamente nel linguaggio. I protocolli informali spesso includono metodi opzionali, dove l'implementazione del metodo può cambiare il comportamento della classe.Ad esempio una classe con uncampo di testo potrebbe avere un "delegato" che dovrebbe implementare un protocollo informale con un metodo opzionale diautocompletamento. Il campo di testo scopre se il delegato implementa o meno il metodo (attraverso il meccanismo dellariflessione), e, in caso positivo, lo chiama per supportare l'autocompletamento.

Un protocollo formale è simile ad un'interfaccia Java o C#. Esso consiste di una lista di metodi che ogni classe può dichiarare di implementare. Il compilatore segnalerà un errore se la classe non implementa ogni metodo dei protocolli che dichiara. Il concetto Objective C di protocolli differisce da quello di interfacce di Java e C# nel fatto che una classe può implementare un protocollo senza dichiararlo esplicitamente. La differenza non è individuabile all'esterno del codice. I protocolli formali non possono fornire nessuna implementazione, essi assicurano semplicemente ai chiamanti che le classi che sono conformi al protocollo forniranno le implementazioni. NellelibrerieNeXT/Apple, i protocolli sono usati di frequente dal sistema ad oggetti distribuiti per rappresentare le capacità di un oggetto eseguito su di un sistema remoto.

La sintassi

@protocolLocking-(void)lock;-(void)unlock;@end

indica che esiste un'idea astratta dilocking che può essere usata; quando è dichiarata in una definizione di classe

@interfaceNomeClasse :NomeSuperClasse<Locking>@end

indica che le istanze diNomeClasse forniranno un'implementazione per i due metodi d'istanza come meglio crederanno. Questa specifica astratta è particolarmente utile per descrivere il comportamento desiderato ad esempio diplugin senza porre nessuna limitazione su quella che dovrà essere la gerarchia d'implementazione.

Tipizzazione dinamica

[modifica |modifica wikitesto]

Objective C (come Smalltalk) può usare latipizzazione dinamica; ovvero rende possibile, per aumentare la flessibilità, inviare ad un oggetto un messaggio non definito nella propria interfaccia. In Objective C un oggetto può "catturare" questo messaggio e può inviarlo ad un altro oggetto (che può rispondere correttamente o inviare a sua volta il messaggio ad un altro oggetto e così via). Questo comportamento è chiamatoforwarding (initaliano:inoltro) odelega del messaggio (si vedasotto). In alternativa, è possibile usare un gestore degli errori nel caso il messaggio non possa essere inoltrato. Nel caso l'oggetto non inoltri il messaggio, non gestisca l'errore o non risponda sarà generato un errore a tempo di esecuzione.

Informazioni di tipizzazione statica possono essere aggiunte eventualmente alle variabili. Tali informazioni sono controllate acompile-time. Nelle istruzioni seguenti, vengono fornite informazioni di tipo sempre più specifiche. Le istruzioni sono equivalenti durante l'esecuzione, ma le informazioni consentono al compilatore di avvisare il programmatore se gli argomenti passati non corrispondono ai tipi specificati. Nella prima istruzione, l'oggetto deve conformarsi al protocolloaProtocol e, nella seconda, deve essere un membro della classeNSNumber.

-setMyValue:(id<aProtocol>)foo;-setMyValue:(NSNumber*)foo;

La tipizzazione dinamica può essere una caratteristica molto potente. Se si implementanoclassi container usando linguaggi a tipizzazione statica come Java (prima della versione 1.5), il programmatore è costretto a scrivere classi container per oggetti generici e poi usare laconversione di tipo per adattarli ad oggetti specifici; tale conversione, comunque, contraddice la disciplina semantica della tipizzazione statica.

Dato che Objective C permette l'invio di un messaggio ad un oggetto che potrebbe non rispondere ad esso, l'oggetto può gestire tale messaggio in altri modi. Uno di questi potrebbe consistere nel suoinoltro (ininglese:forwarding) ad un altro oggetto che sia in grado di rispondere. Il forwarding può essere usato per implementare semplicemente alcunidesign pattern quali l'Observer pattern o ilProxy pattern.

Ilrun-time system di Objective C specifica una coppia di metodi della classeObject

  • metodi di forwarding:
-(retval_t)forward:(SEL)sel:(arglist_t)args;// con GCC-(id)forward:(SEL)sel:(marg_list)args;// con sistemi NeXT/Apple
  • metodi di azione:
-(retval_t)performv:(SEL)sel:(arglist_t)args;// con GCC-(id)performv:(SEL)sel:(marg_list)args;// con sistemi NeXT/Apple

e se un oggetto vuole implementare il forwarding necessita solamente di "sovrascrivere" i metodi di forwarding per definire il proprio comportamento. I metodi di azioneperformv:: non necessitano override.

Ecco un esempio di programma che illustra i fondamenti del forwarding.

Forwarder.h
#import <objc/Object.h>@interfaceForwarder :Object{idrecipient;//L'oggetto a cui vogliamo inoltrare il messaggio}//Metodi accessori-(id)recipient;-(void)setRecipient:(id)_recipient;@end
Forwarder.m
#import "Forwarder.h"@implementationForwarder-forward:(SEL)sel:(marg_list)args{/*     * Controlla se il destinatario risponde effettivamente al messaggio.     * Ciò potrebbe o meno essere desiderabile, ad esempio, se un destinatario     * non risponde al messaggio, potrebbe inoltrare egli stesso il messaggio.     */if([recipientrespondsTo:sel])return[recipientperformv:sel:args];elsereturn[selferror:"Il destinatario non risponde"];}-(id)setRecipient:(id)_recipient{recipient=_recipient;returnself;}-(id)recipient{returnrecipient;}@end
Recipient.h
#import <objc/Object.h>// Un semplice oggetto destinatario.@interfaceRecipient :Object-(id)hello;@end
Recipient.m
#import "Recipient.h"@implementationRecipient-(id)hello{printf("Il destinatario ti saluta!\n");returnself;}@end
main.m
#import "Forwarder.h"#import "Recipient.h"intmain(void){Forwarder*forwarder=[Forwardernew];Recipient*recipient=[Recipientnew];[forwardersetRecipient:recipient];//Setta il destinatario/*     * Si noti che il "forwarder" non risponde al messaggio!     * Esso sarà inoltrato. Tutti i metodi non riconosciuti saranno     * inoltrati al destinatario (se il destinatario li gestisce,     * come detto in "Forwarder").     */[forwarderhello];return0;}

Se dovessimo compilare l'esempio, il compilatore segnalerebbe

$ gcc -x objective-c -Wno-import Forwarder.m Recipient.m main.m -lobjcmain.m: In function `main':main.m:12: warning: `Forwarder' does not respond to `hello'$

Il compilatore segnala ciò che è stato spiegato prima, cheForwarder non risponde al messaggio. In certi casi, questa segnalazione può aiutare a trovare degli errori, ma in questo caso può essere ignorata dato che è stato implementato il forwarding. Per eseguire il programma basterà:

$ ./a.outRecipient says hello!

L'esperienza del mondo dellaprogrammazione strutturata aveva dimostrato che uno dei modi per migliorare la struttura delcodice sorgente è quello di suddividerlo in parti più piccole. Per migliorare questo processo Objective C ha introdotto il concetto dicategoria.

Le categorie permettono di aggiungere separatamente metodi ad una classe. Il programmatore può mettere dei gruppi di metodi correlati in una categoria per renderli più leggibili. Ad esempio, è possibile creare una categoriaControlloOrtografico "su" unoggetto di tipostringa per raccogliere in un unico punto tutti i metodi relativi al controllo ortografico.

Inoltre, i metodi inseriti in una categoria, sono aggiunti allaclasse alrun-time. In questo modo le categorie consentono al programmatore di aggiungere metodi ad una classe esistente senza necessità di ricompilazione e senza la necessità di avere il codice sorgente della stessa. Nell'esempio, se il sistema a disposizione non fornisce il supporto del controllo ortografico nell'implementazione della classe Stringa, è possibile aggiungerlo senza modificarne il sorgente.

I metodi inseriti nelle categorie sono virtualmente parte della classe quando il programma è in esecuzione. Una categoria accede inoltre a tutte le variabili d'istanza della classe, anche quelle private.

Le categorie forniscono una soluzione ai problemi legati alla "fragilità delle classi base" per ciò che concerne i metodi.

Se si dichiara un metodo in una categoria con la stessafirma di un metodo già esistente in una classe, viene adottato il metodo della categoria. In questo modo le categorie, non solo possono aggiungere metodi alle classi, ma possono anche sostituire metodi già esistenti. Questa caratteristica può essere usata per correggere errori in altre classi, semplicemente riscrivendone i metodi, o per cambiare il comportamento di una classe in un dato programma. Se due categorie hanno metodi con la stessa firma, non è definito quale metodo andrà effettivamente in esecuzione.

Diversi linguaggi hanno tentato di aggiungere questa caratteristica in vari modi. Illinguaggio TOM ha portato ulteriormente avanti il concetto consentendo anche di aggiungere variabili. Altri linguaggi, come ad esempio ilSelf, hanno adottato invece soluzioni orientate aiprototipi,

Questo esempio costruisce una classeInteger, definendo prima una classe base con solo pochi metodi implementati e aggiungendo in seguito due categorie,Arithmetic eDisplay, che estendono la classe base. Anche se queste categorie possono accedere alle variabili private della classe base, è buona norma accedere a tali variabili attraverso metodi di servizio che aiutano a tenere le categorie il più indipendenti possibili dalle classi che estendono. Questo è un tipico caso di uso delle categorie per aggiungere o modificare certi metodi della classe base (anche se non è considerata una buona abitudine quella di usare le categorie per sovrascrivere le sottoclassi).

Integer.h
#include<objc/Object.h>@interfaceInteger :Object{intinteger;}-(int)integer;-(id)integer:(int)_integer;@end
Integer.m
#import "Integer.h"@implementationInteger-(int)integer{returninteger;}-(id)integer:(int)_integer{integer=_integer;returnself;}@end
Arithmetic.h
#import "Integer.h"@interfaceInteger(Arithmetic)-(id)add:(Integer*)addend;-(id)sub:(Integer*)subtrahend;@end
Arithmetic.m
#import "Arithmetic.h"@implementationInteger(Arithmetic)-(id)add:(Integer*)addend{return[selfinteger:[selfinteger]+[addendinteger]];}-(id)sub:(Integer*)subtrahend{return[selfinteger:[selfinteger]-[subtrahendinteger]];}@end
Display.h
#import "Integer.h"@interfaceInteger(Display)-(id)showstars;-(id)showint;@end
Display.m
#import "Display.h"@implementationInteger(Display)-(id)showstars{inti,x=[selfinteger];for(i=0;i<x;i++)printf("*");printf("\n");returnself;}-(id)showint{printf("%d\n",[selfinteger]);returnself;}@end
main.m
#import "Integer.h"#import "Arithmetic.h"#import "Display.h"intmain(void){Integer*num1=[Integernew],*num2=[Integernew];intx;printf("Enter an integer: ");scanf("%d",&x);[num1integer:x];[num1showstars];printf("Enter an integer: ");scanf("%d",&x);[num2integer:x];[num2showstars];[num1add:num2];[num1showint];}

la compilazione si effettua così:

gcc -x objective-c main.m Integer.m Arithmetic.m Display.m -lobjc

Si può provare ad omettere le linee#import "Arithmetic.h" e[num1 add:num2] e ad omettereArithmetic.m in compilazione. Il programma girerà lo stesso. Ciò significa che è possibile aggiungere o togliere categorie, dato che se non si ha bisogno di una certa funzionalità offerta da una categoria, basta semplicemente escluderla dalla compilazione.

Objective C permette ad una classe di sostituirne completamente un'altra; questo meccanismo è dettoposing (dall'inglesepose as: fingersi per qualcun altro). La classe sostituita è chiamataclasse target e la classe che sostituisce è chiamataclasse posing. Tutti i messaggi inviati alla classe target vengono ricevuti in sua vece dalla classe posing. Esistono numerose restrizioni da rispettare per effettuare il posing:

  • Una classe può solo sostituirsi a una delle suesuperclassi dirette o indirette.
  • La classe posing non deve definire nessuna nuova variabile d'istanza che sia assente dalla classe target (anche se può definire o sovrascrivere metodi).
  • Nessun messaggio deve essere inviato alla classe target prima del posing

Il posing, similmente alle categorie, consente un aumento globale delle classi esistenti e permette due possibilità assenti nelle categorie:

  • Una classe posing può chiamare metodi sovrascritti attraversosuper, incorporando così l'implementazione della classe target.
  • Una classe posing può sovrascrivere i metodi definiti nelle categorie.

Ad esempio:

@interfaceCustomNSApplication :NSApplication@end@implementationCustomNSApplication-(void)setMainMenu:(NSMenu*)menu{// fa qualcosa col menu}@endclass_poseAs([CustomNSApplicationclass],[NSApplicationclass]);

Questo intercetta ogni invocazione a setMainMenu di NSApplication.

Il posing è stato dichiarato deprecato conMac OS X Leopard e non è disponibile nei run-time a 64 bit.

In C, la direttiva delprecompilatore#include consente di inserire un interofile prima dell'inizio effettivo dellacompilazione. Objective-C aggiunge a questa la direttiva#import, che oltre a svolgere lo stesso ruolo della precedente, evita di includere il file qualora sia già stato incluso in precedenza.

Ad esempio, il file A include i file X e Y, ma X e Y includono ciascuno il file Q, in questo caso Q verrebbe incluso due volte nel file risultante causando così delle definizioni duplicate e quindi un errore in compilazione. Se il file Q venisse incluso con la direttiva#import, solo la prima inclusione verrebbe effettivamente effettuata e tutte le successive verrebbero ignorate.

Alcuni compilatori, compresoGCC, supportano la clausola#import anche per il linguaggio C; il suo uso viene comunque scoraggiato sulla base del fatto che l'utilizzatore dei file da includere dovrebbe distinguere quali file includere solo una volta da quelli progettati per essere inclusi più volte. Questo onere dovrebbe in teoria essere a carico dell'implementatore del file da includere che può usare la direttiva#pragma once o usare latradizionale tecnica:

#ifndef H_PERSONA#define H_PERSONA// ... contenuto di header.h ...#endif

In questo caso le direttive#include e#import diventano equivalenti.

Altre caratteristiche

[modifica |modifica wikitesto]

Objective C ha incluso sin dal suo apparire una lista di caratteristiche che sono tuttora in via di acquisizione in altri linguaggi, oltre ad alcune che sono rimaste sue uniche prerogative. Ciò ha permesso di mettere in luce, partendo dalla realizzazione di Cox (ed in seguito da quella diNeXT), che alcuni considerazioni superano i concetti più strettamente legati al linguaggio. Il sistema deve essere usabile e flessibile nel complesso per poter essere pienamente fruibile.

  • Delegare i metodi ad altri oggetti alrun-time è banale. Basta semplicemente aggiungere una categoria comprendente le modifiche ad un metodo per implementare il forwarding al destinatario della delega.
  • Lachiamata di procedura remota è banale. Basta semplicemente aggiungere una categoria con un metodo che "serializzi" l'invocazione e la inoltri.
  • Loswizzling deipuntatori consente di modificare le classi al run-time. Tipicamente per scopi didebugging se un oggetto la cui memoria è stata rilasciata dovesse venire referenziato per errore.
  • Un oggetto può essere archiviato su unostream (ad esempio unfile) e può essere riletto e recuperato su richiesta.

Objective C++

[modifica |modifica wikitesto]

Objective C++ è unfront-end del compilatoregcc in grado di compilarecodice sorgente che usa una sintassi combinazione di C++ e Objective C. Objective C++ aggiunge a C++ le stesse estensioni che Objective C aggiunge a C. Dato che nulla è stato fatto per unificare le differenze semantiche tra i due linguaggi, sono state applicate alcune restrizioni:

  • una classe C++ non può derivare da una classe Objective C e viceversa
  • inamespace C++ non possono essere dichiarati all'interno di una dichiarazione Objective C
  • le classi Objective C non possono contenere variabili di istanza di classi C++ che non abbiano uncostruttore didefault o che abbiano uno o piùmetodi virtuali, ma si possono usarepuntatori ad oggetti C++ come variabili di istanza senza restrizioni
  • la semantica "per valore" del C++ non può essere applicata agli oggetti Objective C, i quali rimangono accessibili solo mediante puntatori
  • non ci possono essere dichiarazioni Objective C in dichiarazioni ditemplate C++ e viceversa. Comunque è possibile usare tipi Objective C (es. Nomeclasse *) come parametri di template C++
  • La gestione delle eccezioni Objective C è distinta da quella di C++

Analisi del linguaggio

[modifica |modifica wikitesto]

L'implementazione dell'Objective C usa un semplicerun-time system scritto inlinguaggio C che aumenta di poco la dimensione delle applicazioni. Al contrario, la maggior parte dei sistemi object-oriented esistenti quando fu creato (eJava tuttora) usava una grossamacchina virtuale invasiva per l'intero sistema. I programmi scritti in Objective C tendono ad essere di poco più grandi delle dimensioni del lorocodice oggetto e dellelibrerie usate (che generalmente non devono essere incluse nel codice distribuito), al contrario ad esempio dei sistemiSmalltalk dove grandi quantità di memoria sono necessarie semplicemente per aprire unafinestra.

Il linguaggio può essere implementato con un compilatore C (inGCC, prima come unpreprocessore ed in seguito come un modulo del compilatore) piuttosto che con un nuovo compilatore. Ciò consente all'Objective C di sfruttare l'enorme mole di codice, librerie e strumenti già esistenti in C che può essere adattata in Objective C per fornire un'interfaccia object-oriented. Tutti questi fattori riducono le barriere d'ingresso al nuovo linguaggio, fattore che costituì il problema principale di Smalltalk neglianni ottanta.

Le prime versioni di Objective C non supportavano lagarbage collection. Al tempo questa scelta fu oggetto di discussioni e in molti (ai tempi di Smalltalk) la consideravano un lungo "tempo morto" in cui il sistema era reso non più utilizzabile. Anche se qualche implementazione di terze parti (principalmenteGNUstep) aveva già aggiunto questa caratteristica, è stata implementata daApple una tecnica simile tramiteARC inMac OS X Leopard, ma non è disponibile per applicazioni implementate per versioni precedenti delsistema operativo.[6]

Un'altra critica comunemente fatta all'Objective C è quella di non avere un supporto nativo per inamespace. I programmatori sono perciò costretti ad aggiungere prefissi in maniera più o meno arbitraria ai nomi delle classi che implementano, fatto che può causare collisioni. Dal2007 tutte le classi e le funzioni dimacOS in ambienteCocoa hanno il prefisso "NS" (es.NSObject oNSButton) per identificarle chiaramente; "NS" deriva dal nome delle classi definite durante lo sviluppo diNeXTSTEP.

Dato che Objective C è uno strettosuperinsieme del C, non tratta i tipi primitivi del C comefirst-class object.

A differenza del C++, Objective C non supporta l'overloading degli operatori, consente l'ereditarietà solo diretta da una singola classe (vietando così l'ereditarietà multipla). Dato che illinguaggio Java venne influenzato dall'Objective C, la decisione di usare l'ereditarietà singola venne portata anche in Java. In alternativa all'ereditarietà multipla possono essere usate lecategorie ed iprotocolli.

Differenze filosofiche tra Objective C e C++

[modifica |modifica wikitesto]

Il progetto e l'implementazione delC++ e dell'Objective C rappresentano due diversi approcci all'estensione del C.

Oltre allaprogrammazione strutturata del C, C++ supporta direttamente laprogrammazione ad oggetti, la programmazione generica e lametaprogrammazione. C++ è inoltre corredato di una estesa libreria standard che include numeroseclassi container. L'Objective C, invece, aggiunge solo delle caratteristicheobject-oriented al C; esso, nella sua versione più "pura" non offre lo stesso in termini di librerie standard, ma in molti contesti dove viene usato, viene corredato di una libreria sul modello di quella diOpenStep, diCocoa o diGNUstep le quali forniscono funzionalità simili a quelle offerte dalla libreria standard di C++.

Un'altra notevole differenza consiste nel fatto che l'Objective C fornisce un maggior supporto run-time allariflessione rispetto a C++. 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. Comunque è possibile chiedere se due oggetti sono o meno dello stesso tipo (inclusi i tipi predefiniti) e se un oggetto è istanza di una dataclasse (osuperclasse).

L'uso della riflessione fa parte di una più ampia distinzione tra caratteristiche dinamiche (run-time) e statiche (compile-time) dei linguaggi. Sebbene sia Objective C che C++ implementino un misto di entrambe le caratteristiche, Objective C è decisamente più orientato verso le decisioni dinamiche, mentre C++ verso quelle effettuate al momento della compilazione.

Note

[modifica |modifica wikitesto]
  1. (EN)documento Apple, sulists.apple.com(archiviato dall'url originale il 18 giugno 2009).
  2. (EN)documento Apple, sulists.apple.com(archiviato dall'url originale il 24 novembre 2010).
  3. (EN)documento Apple, sudeveloper.apple.com.
  4. (EN)documento Apple, suapple.com.URL consultato il 3 maggio 2019(archiviato dall'url originale il 15 dicembre 2008).
  5. (EN)Portable Object Compiler, suusers.pandora.be(archiviato dall'url originale il 2 agosto 2008).
  6. (EN) Apple, Inc.,Mac OS X Leopard – Xcode 3.0, suapple.com, 22 agosto 2006.URL consultato il 22 agosto 2006(archiviato dall'url originale il 24 ottobre 2007).

Bibliografia

[modifica |modifica wikitesto]

Altri progetti

[modifica |modifica wikitesto]

Altri progetti

Collegamenti esterni

[modifica |modifica wikitesto]
V · D · M
Linguaggio di programmazione C
LibrerieLibreria standard ·GNU C Library ·dietlibc ·uClibc ·Newlib ·EGLIBC
CaratteristicheArray ·Stringhe ·Sintassi ·Tipi e dichiarazioni di variabili ·Funzioni ·Operatori
Linguaggi derivatiC++ ·Objective-C ·D ·C# ·Vala
MiscellaneaIl linguaggio C ·Compilatori
V · D · M
Principalilinguaggi di programmazione(tutti)
ABAP ·Ada ·ALGOL ·APL ·Assembly ·Awk ·BASIC ·C ·C++ ·C# ·COBOL ·Delphi ·Eiffel ·Fortran ·F# ·Haskell ·IDL ·Java ·JavaScript ·J# ·Lisp ·LOGO ·Lua ·ML ·Objective-C ·OCaml ·Pascal ·Perl ·PHP ·PL/I ·PLaSM ·Prolog ·Python ·Ruby ·Rust ·SAS ·Scheme ·sh ·Simula ·Smalltalk ·SQL ·Swift ·Visual Basic
Controllo di autoritàLCCN(EN) sh2008009199 ·GND(DE) 4335874-3 ·BNF(FR) cb14537421z(data) ·J9U(EN, HE) 987007540185705171
 Portale Informatica: accedi alle voci di Wikipedia che trattano di informatica
Estratto da "https://it.wikipedia.org/w/index.php?title=Objective-C&oldid=147129210"
Categoria:
Categorie nascoste:

[8]ページ先頭

©2009-2026 Movatter.jp