2013-04-30 29 views
7

Ich möchte in Objective C dynamisch umwandeln und Instanzeigenschaften zugreifen. Hier ist ein Pseudo-Code:Dynamischer Typ von ID zu Klasse in Objectiv c

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

NSNumber *latitude = obj.latitude; 

Dann wird der Compiler sagt mir folgendes: Eigenschaft ‚Breite‘ nicht auf Objekt gefunden Typ ‚__strong id‘

Entweder Class1 und Class2 sind zentrale Datenelemente und haben fast die gleiche Art von Attributen. In condition1 _fetchedResults gibt Objekte vom Typ Class1 und in condition2 zurück _fetchedResults gibt Objekte vom Typ Class2 zurück.

Könnte mir jemand einen Hinweis geben, wie man diese Art von Problem löst?

Danke!

+0

Ich denke, Sie sollten zuerst sicherstellen, dass was [_fetchedResults objectAtIndex: indexPath.row] zurückgibt, ist die Klasse hat die Breite-Eigenschaft. Außerdem ist das Umwandeln eines Typs NSNagedObject in einen NSManagedObject-Typ falsch. Sie benötigen immer einen NSManagedObjectContext, wenn Sie eine NSManagedObject-Instanz erstellen. –

Antwort

4

Sie können die Eigenschaften durch Key-Wert Coding (KVC) zugreifen:

[obj valueForKey:@"latitude"] 
+0

Beachten Sie, dass die Verwendung von KVC dazu führt, dass Sie keine Typprüfungen vom Compiler durchführen. – ipmcc

+3

@ipmcc Sicher, aber auch "ID" an erster Stelle :-) – Monolo

+0

@Monolo Dies ist unnötig und hat die gleiche Wirkung wie [Obj Breite] – hooleyhoop

1

Die obj Variable muss von einem Typ sein, der die betreffende Eigenschaft hat. Wenn beide Entitäten dieselbe Eigenschaft besitzen, könnte dies beispielsweise dadurch erreicht werden, dass die Eigenschaft für eine gemeinsame Basisklasse deklariert wird. Wenn es nicht angemessen ist, für diese beiden Typen eine gemeinsame Basisklasse zu teilen, dann könnten Sie haben sie ein gemeinsames Protokoll annehmen, wie folgt aus:

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

@interface Class1 (AdoptLatitudeHaving) <LatitudeHaving> 
@end 

@interface Class2 (AdoptLatitudeHaving) <LatitudeHaving> 
@end 

Von dort würden Sie obj als eine id<LatitutdeHaving>, wie dies erklären:

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

NSNumber *latitude = obj.latitude; 

Und das sollte es tun. FWIW, Protokolle sind vergleichbar mit Interfaces in Java.

+0

Was sind die Class1 * und Class2 * Casts für? – hooleyhoop

+0

'objectAtIndex:' gibt eine 'id' nicht eine' id 'zurück. Diese Umwandlungen sind möglicherweise nicht unbedingt notwendig, um Compilerbeschwerden zu vermeiden, aber ich habe versucht, den Code so nah wie möglich an den OP-Code zu bringen. – ipmcc