Objective-C: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
m →Protocolli: fix errore Lint - Tag di chiusura mancante using AWB |
m tag source deprecati, replaced: <source lang= → <syntaxhighlight lang= (33), </source> → </syntaxhighlight> (33) |
||
Riga 56:
==== Proprietà ====
Mentre precedentemente le variabili d'istanza richiedevano metodi espliciti di lettura e scrittura (detti ''getters'' e ''setters''), Objective C 2.0 introduce le proprietà (''property'') con la seguente sintassi:
<
@interface Persona: NSObject {
}
Riga 63:
-(id)initWithName:(NSString)nome eta:(int)eta;
@end
</syntaxhighlight>
Una volta inserite nell'interfaccia, si può accedere alle proprietà usando la notazione descritta nell'esempio:
<
Il compilatore traduce questa notazione in chiamate di metodi accessori. L'istruzione precedente è equivalente a:
<
==== Enumerazione veloce ====
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 *persona in laGente)
NSLog(@"%@ ha %i anni.", persona.nome, persona.eta);
</syntaxhighlight>
==== Portable Object Compiler ====
Riga 86:
Si dice che un oggetto chiamato ''ogg'' la cui [[classe (informatica)|classe]] implementa il metodo ''faiQualcosa'', ''risponde'' al messaggio ''faiQualcosa''. L'invio del messaggio ''faiQualcosa'' all'oggetto ''ogg'' è espresso da:
<
mentre l'azione equivalente in C++ e Java sarebbe espressa da:
<
In questo modo è possibile inviare messaggi ad un oggetto anche se l'oggetto ''non è capace'' di rispondere. Questo differisce dai linguaggi [[tipo di dato|tipizzati]] staticamente come C++ e [[Java (linguaggio di programmazione)|Java]] nei quali tutte le chiamate devono essere di metodi predefiniti.
Riga 99:
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"
Riga 122:
@end
</syntaxhighlight>
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 dei [[Unified Modeling Language|diagrammi UML]] dove i due segni rappresentano rispettivamente i metodi privati e pubblici.
Riga 130:
La convenzione usata è quella di assegnare il nome al file basandosi sul nome della classe, nell'esempio "NomeDellaClasse.m"
<
//definizione dell'implementazione: "NomeDellaClasse.m"
Riga 160:
@end
</syntaxhighlight>
I metodi sono scritti in maniera diversa dalle [[funzione (informatica)|funzioni]] in stile C. Ad esempio, una funzione, sia in C che in Objective C segue la seguente forma generale:
<
int fai_la_radice_quadrata(int i)
{
return radice_quadrata(i);
}
</syntaxhighlight>
che avrà come prototipo:
<
L'implementazione come metodo diverrà:
<
- (int) fai_la_radice_quadrata:(int) i
{
return [self radice_quadrata: i];
}
</syntaxhighlight>
Un approccio più canonico alla scrittura del metodo sarebbe quello di citare il primo argomento nel nome del selettore:
<
- (int) faiLaRadiceQuadrataDiInt: (int) i
{
return [self radiceQuadrataDiInt:i];
}
</syntaxhighlight>
Questa sintassi può apparire complicata, ma consente di assegnare i nomi ai [[parametro (informatica)|parametri]], ad esempio:
<
- (int) changeColorWithRed:(int) r green:(int) g blue:(int) b
</syntaxhighlight>
può essere invocato così:
<
[myColor changeColorWithRed:5 green:2 blue:6];
</syntaxhighlight>
Le rappresentazioni interne di questi metodi possono variare con le diverse implementazioni di Objective C.
Riga 219:
La sintassi
<
@protocol Locking
- (void)lock;
- (void)unlock;
@end
</syntaxhighlight>
indica che esiste un'idea astratta di [[lock]]ing che può essere usata; quando è dichiarata in una definizione di classe
<
@interface NomeClasse : NomeSuperClasse <Locking>
@end
</syntaxhighlight>
indica che le istanze di ''NomeClasse'' forniranno un'implementazione per i due metodi d'istanza come meglio crederanno. Questa specifica astratta è particolarmente utile per descrivere il comportamento desiderato ad esempio di [[plugin (informatica)|plugin]] senza porre nessuna limitazione su quella che dovrà essere la gerarchia d'implementazione.
Riga 236:
Informazioni di tipizzazione statica possono essere aggiunte eventualmente alle variabili. Tali informazioni sono controllate nel [[compile-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 protocollo ''aProtocol'' e, nella seconda, deve essere un membro della classe ''NSNumber''.
<
- setMyValue:(id <aProtocol>) foo;
- setMyValue:(NSNumber*)foo;
</syntaxhighlight>
La tipizzazione dinamica può essere una caratteristica molto potente. Se si implementano [[classe container|classi 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 la [[conversione di tipo]] per adattarli ad oggetti specifici; tale conversione, comunque, contraddice la disciplina semantica della tipizzazione statica.
Riga 247:
Il [[run-time system]] di Objective C specifica una coppia di metodi della classe <code>Object</code>
* metodi di forwarding:
<
- (retval_t) forward:(SEL) sel :(arglist_t) args; // con GCC
- (id) forward:(SEL) sel :(marg_list) args; // con sistemi NeXT/Apple
</syntaxhighlight>
* metodi di azione:
<
- (retval_t) performv:(SEL) sel :(arglist_t) args; // con GCC
- (id) performv:(SEL) sel :(marg_list) args; // con sistemi NeXT/Apple
</syntaxhighlight>
e se un oggetto vuole implementare il forwarding necessita solamente di "[[override|sovrascrivere]]" i metodi di forwarding per definire il proprio comportamento. I metodi di azione <code>performv::</code> non necessitano override.
Riga 262:
; ''Forwarder.h''
<
#import <objc/Object.h>
Riga 275:
@end
</syntaxhighlight>
; ''Forwarder.m''
<
#import "Forwarder.h"
Riga 307:
}
@end
</syntaxhighlight>
; ''Recipient.h''
<
#import <objc/Object.h>
Riga 317:
- (id) hello;
@end
</syntaxhighlight>
; ''Recipient.m''
<
#import "Recipient.h"
Riga 333:
@end
</syntaxhighlight>
; main.m
<
#import "Forwarder.h"
#import "Recipient.h"
Riga 357:
return 0;
}
</syntaxhighlight>
==== Note ====
Riga 391:
; ''Integer.h''
<
#include <objc/Object.h>
Riga 402:
- (id) integer: (int) _integer;
@end
</syntaxhighlight>
; ''Integer.m''
<
#import "Integer.h"
Riga 420:
}
@end
</syntaxhighlight>
; ''Arithmetic.h''
<
#import "Integer.h"
Riga 430:
- (id) sub: (Integer *) subtrahend;
@end
</syntaxhighlight>
; ''Arithmetic.m''
<
#import "Arithmetic.h"
Riga 447:
}
@end
</syntaxhighlight>
; ''Display.h''
<
#import "Integer.h"
Riga 457:
- (id) showint;
@end
</syntaxhighlight>
; ''Display.m''
<
#import "Display.h"
Riga 481:
}
@end
</syntaxhighlight>
; ''main.m''
<
#import "Integer.h"
#import "Arithmetic.h"
Riga 505:
[num1 showint];
}
</syntaxhighlight>
==== Note ====
Riga 525:
Ad esempio:
<
@interface CustomNSApplication : NSApplication
@end
Riga 537:
class_poseAs ([CustomNSApplication class], [NSApplication class]);
</syntaxhighlight>
Questo intercetta ogni invocazione a setMainMenu di NSApplication.
Riga 549:
Alcuni compilatori, compreso [[GNU Compiler Collection|GCC]], 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 la [[Include guard|tradizionale tecnica]]:
<
#ifndef H_PERSONA
#define H_PERSONA
// ... contenuto di header.h ...
#endif
</syntaxhighlight>
In questo caso le direttive ''#include'' e ''#import'' diventano equivalenti.
|