2013-04-30 14 views
7

Vorrei eseguire il cast dinamico in Objective C e accedere alle proprietà dell'istanza. Ecco un codice pseudo:Trasmissione di tipi dinamici dall'ID alla classe nell'obiettivo c

id obj; 
if (condition1) 
    obj = (Class1*)[_fetchedResults objectAtIndex:indexPath.row]; 
else 
    obj = (Class2*)[_fetchedResults objectAtIndex:indexPath.row]; 

NSNumber *latitude = obj.latitude; 

Poi il compilatore mi dice il seguente: proprietà 'di latitudine' non trovato in oggetto di tipo '__strong id'

In entrambi i Class1 e Class2 sono entità di dati di base e hanno quasi lo stesso tipo di attributi. In condizione1 _fetchedResults restituisce oggetti di tipo Classe1 e in condizione2 _fetchedResults restituisce oggetti di tipo Classe2.

Qualcuno potrebbe darmi un suggerimento su come risolvere questo tipo di problema?

Grazie!

+0

Penso che dovresti assicurarti in primo luogo che cosa restituisce [_fetchedResults objectAtIndex: indexPath.row] se la classe ha la proprietà latitude. Inoltre, non è possibile eseguire il cast di un tipo NSManagedObject none su un tipo NSManagedObject. È necessario un NSManagedObjectContext ogni volta e tuttavia si crea un'istanza NSManagedObject. –

risposta

4

È possibile accedere alle proprietà tramite valore-chiave Coding (KVC):

[obj valueForKey:@"latitude"] 
+0

Tieni presente che l'utilizzo di KVC per eseguire questa operazione ti deruba da qualsiasi tipo di controllo dal compilatore. – ipmcc

+3

@ipmcc Certo, ma lo stesso vale per l'uso di 'id' in primo luogo :-) – Monolo

+0

@Monolo Non è necessario e ha lo stesso effetto di [obj latitude] – hooleyhoop

1

La variabile obj deve essere di un tipo che ha la proprietà in questione. Se entrambe le entità hanno la stessa proprietà, un modo per ottenere ciò sarebbe che la proprietà venga dichiarata su una classe base comune. Se non è appropriato per questi due tipi di condividere una classe base comune, allora si potrebbe avere li adottano un protocollo comune, in questo modo:

@protocol LatitudeHaving 
@property (copy) NSNumber* latitude; 
@end 

@interface Class1 (AdoptLatitudeHaving) <LatitudeHaving> 
@end 

@interface Class2 (AdoptLatitudeHaving) <LatitudeHaving> 
@end 

Da lì, si dovrebbe dichiarare obj ad essere un id<LatitutdeHaving>, in questo modo:

id<LatitudeHaving> obj; 
if (condition1) 
    obj = (Class1*)[_fetchedResults objectAtIndex:indexPath.row]; 
else 
    obj = (Class2*)[_fetchedResults objectAtIndex:indexPath.row]; 

NSNumber *latitude = obj.latitude; 

E questo dovrebbe farlo. FWIW, i protocolli sono simili alle interfacce in Java.

+0

per cosa sono i cast di Class1 * e Class2 *? – hooleyhoop

+0

'objectAtIndex:' restituisce un 'id' non un' id '. Questi cast potrebbero non essere strettamente necessari per evitare i reclami del compilatore, ma stavo cercando di rendere il codice il più vicino possibile al codice dell'OP. – ipmcc