{"id":551,"date":"2009-11-05T15:51:53","date_gmt":"2009-11-05T14:51:53","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=551"},"modified":"2009-12-14T16:12:30","modified_gmt":"2009-12-14T15:12:30","slug":"l006-objective-c-i","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/l006-objective-c-i\/","title":{"rendered":"L#006 &#8211; Objective-C (Parte I) Oggetti, Messaggi, Classi"},"content":{"rendered":"<p>Il linguaggio Objective-C \u00e8 un linguaggio di programmazione creato per permettere lo sviluppo di applicazioni tramite il sofisticato paradigma di programmazione object-oriented. Objective-C \u00e8 definito come un piccolo ma potente set di estensioni allo standard ANSI C. Le estensioni introdotte sono principalmente basate su Smalltalk, uno dei primi linguaggi di programmazione orientati agli oggetti. Objective-C \u00e8 stato quindi creato per offrire la possibilit\u00e0 ai numerosi programmatori C di lavorare, in modo semplice e diretto, con un linguaggio ad oggetti.<!--more--><\/p>\n<p>Gli ambienti di sviluppo object-oriented sono composti solitamente di diverse parti:<\/p>\n<ul>\n<li>Un lunguaggio di programmazione ad oggetti (nel nostro caso Objective-C)<\/li>\n<li>Una libreria di oggetti preconfezionati (ad esempio il framework Cocoa)<\/li>\n<li>Una suite di strumenti di sviluppo (Xcode, Interface Builder, Instruments)<\/li>\n<li>Un ambiente di runtime (iPhone Simulator)<\/li>\n<\/ul>\n<h4>Gli oggetti<\/h4>\n<p>Un oggetto \u00e8 un entit\u00e0 che possiede dei dati a cui associa delle particolari operazioni che possono utilizzare o modificare i dati stessi. In Objective-C queste operaszioni sono conosciute come &#8220;<strong>Metodi<\/strong> degli oggetti&#8221;. I dati interessati sono le sue <strong>variabili<\/strong> di istanza. In sostanza la struttura di un oggetto \u00e8 formata da alcuni dati (variabili) e un gruppo di procedure (metodi) in un un unico elemento.<\/p>\n<p>Per esempio, se state scrivendo un programma di disegno che permette all&#8217;utente di creare un&#8217;immagine composta da linee, cerchi, rettangoli, testi, immagini bitmap e cos\u00ec via, dovreste creare delle classi per ogni elemento base che l&#8217;utente puo&#8217; manipolare. Un oggetto rettangolo, per esempio, potrebbe avere variabili di istanza che identificano la posizione del rettangolo all&#8217;interno del disegno, la sua larghezza e la sua altezza. Altre variabili potrebbero invece definirne il colore, decidere se questo va riempito o meno con questo colore o che tipo di linea che deve essere usata per mostrare il rettangolo. La classe Rettangolo potrebbe inoltre avere metodi per settare questi valori, ovvero posizione, dimensione, colore, stato riempimento e tipo di linea insieme ad un metodo che mostra poi il tutto sul display.<\/p>\n<p>In Objective-C le variabili di istanza di un oggetto sono interne all&#8217;oggetto. Generalmente \u00e8 possibile accedere allo stato di un oggetto solo attraverso i suoi metodi (\u00e8 inoltre possibile specificare se sottoclassi o altri oggetti possono accedere direttamente alle variabili di un oggetto secondo le direttive di visibilit\u00e0). Per altri oggetti che necessitano di estrapolare dati da un oggetto, deve esistere un metodo che le fornisca. Per esempio, un Rettangolo potrebbe avere un metodo che mostra la sua dimensione e posizione.<\/p>\n<p>Inoltre, un oggetto vede i soli oggetti che sono stati disegnati per esso, non si pussono quindi utilizzare, anche erroneamente, metodi destinati ad altri oggetti. Come nel C le funzioni &#8220;proteggono&#8221; le loro variabili locali nascondendole dal resto del programma, un oggetto nasconde le sue variabili e i suoi metodi.<\/p>\n<h4>Messaggi<\/h4>\n<p><strong>Sintassi (standard)<\/strong><\/p>\n<p>Per dire ad un oggetto di fare qualcosa occorre inviargli un messaggio che gli dice di applicare un determinato metodo. In Objective-C l&#8217;espressione del messaggio va racchiusa tra parentesi quadre:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n[receiver message]\r\n<\/pre>\n<p>Il ricevitore del messaggio (<em>receiver<\/em>) \u00e8 un oggetto, mentre <em>message<\/em> \u00e8 il messaggio che gli dice cosa deve fare. Nel codice il messaggio \u00e8 semplicemente il nome del metodo pi\u00f9 eventuali argomenti da passare. Quando il messaggio viene inviato, il sistema di runtime seleziona il metodo appropriato dal repertorio dell&#8217;oggetto ricevente e lo invoca.<\/p>\n<p>Per esempio, questo messaggio dice all&#8217;oggetto <em>myRectangle<\/em> di invocare il suo metodo <em>display<\/em>, che non fa altro che mostrare il rettangolo stesso:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n[myRectangle display];\r\n<\/pre>\n<p>Il messaggio termina con &#8220;;&#8221; che rappresenta il termine di un&#8217;istruzione in C e di conseguenza va utilizzato anche in Objective-C.<\/p>\n<p>Il nome del metodo nel messaggio serve per selezionare appunto il metodo dal set di quelli disponibili. Per questo motivo i nomi dei metodi nei messaggi sono spesso definiti selettori.<\/p>\n<p>I metodi possono inoltre accettare eventuali parametri, o &#8220;argomenti&#8221;. In un messaggio con un singolo argomento occorre inserire il simbolo &#8220;:&#8221; (duepunti) subito dopo il nome del metodo seguito quindi dall&#8217;argomento. Questo costrutto \u00e8 chiamato keyword, le keyword sono formate dal nome del metodo, dal carattere &#8220;:&#8221; e a seguire l&#8217;argomento, come mostrato in questo esempio:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n[myRectangle setWidth:20.0];\r\n<\/pre>\n<p>Il nome del metodo comprende quindi tutti i caratteri, inclusi i duepunti e l&#8217;argomento, ma non include elementi come il tipo di dato da restituire o i tipi di dato dei parametri. Il messaggio seguente, errato, dice all&#8217;oggetto <em>myRectangle<\/em> di settare la sua origine alle coordinate (30.0, 50.0):<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n\/\/ Questo \u00e8 un esempio errato dell'uso di argomenti multipli*\r\n[myRectangle setOrigin:30.0 :50.0];\r\n<\/pre>\n<p>*<strong>Nota:<\/strong> In C e di conseguenza in Objective-C tutto ci\u00f2 che sta di seguito ai caratteri &#8220;\/\/&#8221; \u00e8 considerato un commento. Un commento non viene considerato in fase di compilazione del programma e il suo scopo \u00e8 semplicemente di rendere pi\u00f9 leggibile e comprensibile il codice sorgente delle applicazioni. I caratteri &#8220;\/\/&#8221; vengono usati per inserire commenti di una sola riga. Se si volesse inserire un commento composto di pi\u00f9 riche occorre semplicemente inserirlo tra i caratteri &#8220;\/*&#8221; di inizio commento e &#8220;*\/&#8221; di fine commento.<\/p>\n<p>Dato che i due punti &#8220;:&#8221; sono parte del nome del metodo, il metodo dell&#8217;esempio errato appena citato risulta essere <strong>setOrigin::<\/strong>. Esso ha 2 simboli &#8220;:&#8221; e riceve due argomenti. In questo esempio in particolare il secondo argomento risulta privo di etichetta (prima dei &#8220;:&#8221;) e perci\u00f2 \u00e8 difficile determinare il tipo o lo scopo di questo argomento. Per questo \u00e8 errato.<\/p>\n<p>I nomi dei metodi dovrebbero includere un&#8217;etichetta che identifichi gli argomenti. Per esempio, il metodo citato sopra per la classe <em>Rectangle<\/em> potrebbe essere implementato con <em>setOriginX:Y:<\/em><\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n\/\/ Questo \u00e8 un esempio corretto dell'uso di argomenti multipli\r\n[myRectangle setOriginX: 30.0 y: 50.0];\r\n<\/pre>\n<p>Come nelle funuzioni in C, i metodi possono restituire dei valori. Il seguente esempio setta la variabile <em>isFilled<\/em> a <em>YES<\/em> se <em>myRectangle<\/em> \u00e8 disegnato come un solido riempito, o <em>NO<\/em> se non ha riempimento ed \u00e8 formato dalla sola linea.:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\nBOOL isFilled;\r\nisFilled = [myRectangle isFilled];\r\n<\/pre>\n<p>Una variabile e un metodo possono avere lo stesso nome.<\/p>\n<p>Un messaggio pu\u00f2 essere inoltre <strong>nidificato<\/strong> all&#8217;interno di un altro. Qui ad esempio il colore di un rettangolo \u00e8 impostato con il colore di un altro:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n[myRectangle setPrimaryColor:[otherRect primaryColor]];\r\n<\/pre>\n<p><strong>Sintassi col punto (dot syntax)<\/strong><\/p>\n<p>Objective-C offre la possibilit\u00e0 di usare un altro tipo di sintassi, alternativa alla notazione classica tra parentesi quadre [.. ..] grazie all&#8217;operatore punto &#8220;.&#8221; per invocare i metodi. Questa notazione \u00e8 particolarmente utile quando si vuole accedere o modificare propriet\u00e0 che sono di un altro oggetto. <\/p>\n<p>E&#8217; possibile usare la sintassi con il punto come mostrato nei seguenti esempi:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\nmyInstance.value = 10;\r\nprintf(\"myInstance value: %d\", myInstance.value);\r\n<\/pre>\n<p>La porzione di codice qui sopra \u00e8 esattamente equivalente alla seguente:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n[myInstance setValue:10];\r\nprintf(\"myInstance value: %d\", [myInstance value]);\r\n<\/pre>\n<p>E&#8217; possibile quindi usare questa sintassi come mostrato nel seguente esempio:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\nGraphic *graphic = [[Graphic alloc] init];\r\nNSColor *color = graphic.color;\r\nCGFloat xLoc = graphic.xLoc;\r\nBOOL hidden = graphic.hidden;\r\nint textCharacterLength = graphic.text.length;\r\n\r\nif (graphic.textHidden != YES) {\r\n    graphic.text = @\"Hello\";\r\n}\r\n\r\ngraphic.bounds = NSMakeRect(10.0, 10.0, 20.0, 120.0);\r\n<\/pre>\n<p>Utilizzando la sintassi classica con le quadre dell&#8217;Objective-C avremmo dovuto scrivere:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\nGraphic *graphic = [[Graphic alloc] init];\r\nNSColor *color = [graphic color];\r\nCGFloat xLoc = [graphic xLoc];\r\nBOOL hidden = [graphic hidden];\r\nint textCharacterLength = [[graphic text] length];\r\n\r\nif ([graphic isTextHidden] != YES) {\r\n    [graphic setText:@\"Hello\"];\r\n}\r\n\r\n[graphic setBounds:NSMakeRect(10.0, 10.0, 20.0, 120.0)];\r\n<\/pre>\n<p>Un vantaggio di questa sintassi \u00e8 che il compilatore pu\u00f2 segnalare un errore quando, ad esempio, incontra un metodo che tenta di scrivere qualcosa in una proriet\u00e0 in sola lettura.<\/p>\n<p>E&#8217; inoltre possibile usare istruzioni composte da entrambi i tipi di sintassi:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\nNSMutableData *data = [NSMutableData dataWithLength:1024];\r\ndata.length += 1024;\r\ndata.length *= 2;\r\ndata.length \/= 4;\r\n<\/pre>\n<p>Che equivale a:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n[data setLength:[data length] + 1024];\r\n[data setLength:[data length] * 2];\r\n[data setLength:[data length] \/ 4];\r\n<\/pre>\n<p>Di seguito altri esempi validi, mostrati utilizzando entrambi i tipi di sintassi:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n\/\/ ciascun membro del percorso \u00e8 un oggetto\r\nx = person.address.street.name;\r\nx = [[[person address] street] name];\r\n\r\n\/* Il percorso contiene una truttura C che andr\u00e0 in crash \r\nse la finestra \u00e8 nulla o contentView \u00e8 nullo *\/\r\ny = window.contentView.bounds.origin.y;\r\ny = [[window contentView] bounds].origin.y;\r\n\r\n\/\/ altro esempio\r\nperson.address.street.name = @\"Oxford Road\";\r\n[[[person address] street] setName: @\"Oxford Road\"];\r\n<\/pre>\n<p><strong>Self<\/strong><\/p>\n<p>Se si vuole accedere ad un metodo dell&#8217;oggetto stesso, occorre usare la sintassi mostrata di seguito:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\nself.age = 10;\r\n<\/pre>\n<h4>Classi<\/h4>\n<p>Un programma object-oriented \u00e8 tipicamente composto da una gran variet\u00e0 di oggetti. Un programma basato sul framework Cocoa, (il set di sviluppo per Mac per intenderci), ad esempio, potrebbe avere oggetti come NSMatrix, NSWindow, NSDictionary, NSFont, NSText e molti altri. Questi programmi spesso usano inoltre pi\u00f9 oggetti dello stesso tipo.<\/p>\n<p>In Objective-C per definire gli oggetti, occorre definire le loro classi. La definizione della classe non \u00e8 nient&#8217;altro che un prototipo per il tipo di oggetto. In esso vanno dichiarate le variabili di istanza e un set di metodi che saranno disponibili per tutti gli oggetti della classe.<\/p>\n<p>Il compilatore creer\u00e0 un solo oggetto accessibile per ogni classe, un oggetto che sa come costruire nuovi oggetti della stessa classe. L&#8217;oggetto classe \u00e8 la versione compilata della classe, gli oggetti creati sono invece istanze di questa classe. Gli oggetti che eseguono il lavoro principali nel programma quindi sono delle istanze create dall&#8217;oggetto classe durante l&#8217;esecuzione.<\/p>\n<p>Tutte le istanze di una classe hanno lo stesso set di metodi a disposizione e ovviamente lo stesso set di variabili, prese dallo stesso &#8220;stampo&#8221;.<\/p>\n<p>Ogni oggetto avr\u00e0 quindi le proprie variabili, mentre i metodi sono condivisi da tutte le istanze.<\/p>\n<p>Per convenzione i nomi delle classi dovrebbero iniziare con una lettera maiuscola (come la classe dell&#8217;esempio sopra &#8220;Rectangle&#8221;). I nomi delle istanze, invece, dovrebbero iniziare con una lettera minuscola (ad esempio &#8220;myRectangle&#8221;)<\/p>\n<p><strong>Ereditariet\u00e0<\/strong><\/p>\n<p>Ogni nuova classe creata \u00e8 basata su un&#8217;altra classe dalla quale eredita tutti i metodi e le variabili di istanza. La nuova classe semplicemente aggiunge o modifica ci\u00f2 che eredita. Non \u00e8 quindi necessario duplicare il codice ereditato.<\/p>\n<p>L&#8217;ereditariet\u00e0 collega quindi tutte le classi in una struttura gerarchica ad albero, con una sola classe alla radice. Quando scriviamo codice basato sul framework Foundation, l&#8217;oggetto alla radice \u00e8 solitamente NSObject. Tutti gli oggetti al di sotto di questo ereditano quindi variabili e metodi, aggiungendone altri o modificandone alcuni ereditati. Tutti gli oggetti, escluso quello alla radice, hanno una classe subito sopra, dal quale ereditano tutto, chiamata superclasse e ogni oggetto ha o puo&#8217; avere delle sottoclassi a cui trasmettere le sue variabili e i suoi metodi.<\/p>\n<p>Di seguito un&#8217;immagine che mostra visivamente questa struttura gerarchica:<\/p>\n<p><center><br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/11\/graphichierarchy.gif\" alt=\"graphichierarchy\" title=\"graphichierarchy\" width=\"334\" height=\"184\" class=\"aligncenter size-full wp-image-654\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/11\/graphichierarchy.gif 334w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/11\/graphichierarchy-300x165.gif 300w\" sizes=\"auto, (max-width: 334px) 100vw, 334px\" \/><br \/>\n<\/center><\/p>\n<p>La figura sopra mostra la classe Square come una sottoclasse della classe Rectangle e la classe Rectangle \u00e8 una sottoclasse di Shape, Shape \u00e8 una sottoclasse di Graphic, e quest&#8217;ultima \u00e8 una sottoclasse di NSObject. L&#8217;ereditariet\u00e0 \u00e8 cumulativa. Quindi un oggetto Square ha i metodi e le variabili definite in Rectangle, Shape, Graphic e NSObject, come se fossero definite direttamente nella classe Square. Questo \u00e8 un modo semplice per dire che un oggetto Square non \u00e8 solo un oggetto Square, ma anche un oggetto Rectangle, Shape, Graphic e NSObject.<\/p>\n<p>Ogni classe puo&#8217; essere vista come una specializzazione o un adattamento di un&#8217;altra classe. Ogni sottoclasse successiva modifica alcune parti di ci\u00f2 che eredita, quindi, nel nostro esempio, la classe <em>Square<\/em> definisce solo il minimo necessario per modificare un rettangolo in un quadrato.<\/p>\n<p>Quando definiamo una classe, la linkiamo nella gerarchia dichiarando la sua superclasse. Ogni classe che verr\u00e0 creata deve essere una sottoclasse di un&#8217;altra, a meno che non stiate definendo una nuova classe radice. <\/p>\n<p>Le potenziali superclassi disponibili sono in abbondanza. Cocoa include la classe NSObject e diversi framework contengono definizioni per oltre 250 classi aggiuntive. Alcune sono classi che potreste usare cos\u00ec come sono, mentre altre potrebbero essere adattate secondo le proprie esigenze definendo da esse nuove sottoclassi.<\/p>\n<p>Molte classi del framework definisco tutto cio&#8217; di cui possiamo aver bisogno , ma lasciano alcune specifiche per essere implementate in sottoclassi. Possiamo quidni creare oggetti molto sofisticati scrivendo solo una piccola porzione di codice e riusare l&#8217;ottimo codice prodotto dagli esperti programmatori dei framework.<\/p>\n<p>Nella prossima lezione andremo a vedere come si definisce una classe da utilizzare nel nostro programma.<\/p>\n<p>(Tradotto dalla documentazione ufficiale Apple)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Il linguaggio Objective-C \u00e8 un linguaggio di programmazione creato per permettere lo sviluppo di applicazioni tramite il&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[37,36,5,35,4,17],"class_list":["post-551","post","type-post","status-publish","format-standard","hentry","category-guide-teoriche","tag-classi","tag-messaggi","tag-objective-c","tag-oggetti","tag-programmazione","tag-teoria"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/551","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=551"}],"version-history":[{"count":35,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/551\/revisions"}],"predecessor-version":[{"id":1307,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/551\/revisions\/1307"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=551"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=551"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=551"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}