Ooooh ... domanda divertente. La risposta è un c-ismo.
considerare:
@interface MyClass : NSObject
@end
@implementation MyClass
@end
Ora, supponiamo di avere:
...
MyClass *m = nil;
...
In tale contesto, il compilatore vede MyClass
come una definizione di tipo. Il *
dice che la variabile m
è un pointer to a hunk o' memory that contains one (or many -- don't forget your C pointer-fu) MyClass instances
.
In altre parole, MyClass
è un tipo.
Ma, nel contesto di qualcosa come:
[someInstance isKindOfClass: x ];
x
deve essere un rvalue o, in termini umani, il valore di un'espressione. Un tipo, tuttavia, non può essere utilizzato come valore.
Questo [MyClass class]
funziona in realtà è un po 'un hack, sia nella lingua che nel compilatore, in quanto la grammatica consente specificamente a un nome di tipo di essere il destinatario del messaggio (per essere l'obiettivo di una chiamata di metodo).
E, come un dato di fatto, si può fare:
typedef MyClass Foo;
....
[MyClass class];
[Foo Class];
sarà tutto il lavoro. Tuttavia, non è possibile effettuare le seguenti operazioni ma il messaggio di errore è illuminante:
[NSUInteger class];
errore: 'NSUInteger' non è un nome di classe Objective-C o alias
Ora , perché non caso speciale dappertutto come un nome spoglio?
Questo collude nomi di tipi e valori e si finisce rapidamente per dover inghiottire qualcosa come [foo isKindOfClass: (MyClass)];
mentre il barattolo su [foo isKindOfClass: (MyClass *)];
che poi invade il territorio di typecasting in modo piuttosto scomodo.
+1 domanda interessante! Non ci avevo mai pensato prima (almeno non in questo modo) –