2014-04-04 12 views
11

Fingere ho una categoria sulla NSObject che definisce il seguente metodo:Perché la sintassi del punto non può essere utilizzata su un metodo il cui tipo di ritorno è instancetype?

+ (instancetype)allocTemplate 
{ 
    id instance = [self new]; 

    return instance; 
} 

e ho la seguente classe:

@interface FDActor : NSObject 

@property (nonatomic, copy) NSString *name; 

+ (void)sayHi;  

@end 


@implementation FDActor 

+ (void)sayHi 
{ 
    [self allocTemplate].name; 
} 

@end 

Come mai [self allocTemplate].name errori fuori al momento della compilazione se stessi è FDActor?

Sono consapevole che funziona se si utilizza la normale sintassi di invio dei messaggi, ma sono esplicitamente interessato all'errore di sintassi del punto.

+0

Qual è l'errore? Ho provato qualcosa di simile e il mio è stato compilato. –

+0

Nome proprietà 'non trovato su oggetto di tipo' id '. Per essere chiari, non intendo sostituire "self" con "FDActor". Intendo chiamare quel metodo all'interno di un metodo di classe all'interno di FDActor. –

+0

Se la categoria è su NSObject, non instancetype restituire qualcosa digitato come NSObject? – michaels

risposta

3

Sembra che instancetype sia utilizzato solo per il controllo del tipo durante l'assegnazione, pertanto FDActor *actor = [FDActor allocTemplate] non genera un avviso.

Se si restituisce il tipo restituito di allocTemplate, il problema scompare.

- (void)sayHi { ((__typeof__(self))[[self class] allocTemplate]).name; }

ma si noti che questo funziona solo in un metodo di istanza in quanto il typeof un'istanza è un altro esempio. Si noti inoltre che, poiché ora si digita esplicitamente il valore restituito, il metodo allocTemplate non è più necessario, se tutti cercavano il controllo del tipo, possiamo anche solo eseguire il cast di nil e funzionerà.

Se cerchiamo la stessa cosa in un metodo di classe non funziona

+ (void)sayHi { ((__typeof__(self) *)[self allocTemplate]).name; } Questo perché (__typeof__(self) *) facitori non restituiscono FDActor * ma Class * che ARC si lamenterà. Sembra che non sia possibile risolvere le informazioni sul tipo FDActor * in modo generico da un metodo di classe in fase di compilazione.

Mi aspettavo piuttosto che la parola chiave instancetype fosse un po 'più utile.

1

Il messaggio di errore indica. [self allocTemplate] è un id. Sintassi della proprietà mai funziona su id.

Si noti che questo fa lavoro:

[FDActor allocTemplate].name; 

Penso che la classe a cui instancetype deve essere correlato deve essere specificato nel bando; altrimenti torniamo semplicemente allo id.

+0

Capisco questo, ma qual è il punto di instancetype allora? –

+0

http://nshipster.com/instancetype/ – matt

+1

Scusa, non volevo dire che non so quale sia l'istancetipo. Voglio dire qual è il punto di instancetype se viene trattato come un id per tutti i metodi o le proprietà di sintassi del punto chiamato su di esso. L'intero punto dell'istanza è che è riconosciuto come un tipo di qualsiasi classe chiamata metodo. Voglio controllare il tipo sulle chiamate al metodo e non solo sui compiti. –

0

Prenderò una pugnalata a questo, con il disclaimer che non capisco appieno come il supporto instancetype sia effettivamente implementato, per non parlare di tutti i dettagli nitidi del sistema di controllo del tipo del compilatore. In altre parole, questa è la mia ipotesi migliore e non una risposta autorevole o completa ...

Dopo la compilazione, i metodi Objective-C sono in realtà funzioni, in cui self è il primo argomento della funzione e viene digitato id. In modo da avere: il trattamento

void sayHi(id self, SEL _cmd) 
{ 
    [self allocTemplate].name; // Actually calls to objc_msgSend, but that doesn't matter here 
} 

del compilatore del tipo di valore restituito da +allocTemplate qui sembra essere correlato a questo. Se si cambia auto ad un esplicito FDActor, l'errore scompare. Certamente, per i metodi - al contrario delle proprietà - il tipo di compilatore self come ci si aspetterebbe e avviserà (o errore in ARC) per i metodi a cui il self non sembra rispondere. Sembra che questa sia forse una differenza (bug?) Nel controllo del compilatore per i metodi disponibili rispetto alle proprietà nel contesto di instancetype.

Problemi correlati