2013-04-30 12 views
7

Chciałbym rzutować dynamicznie w Objective C i uzyskać dostęp do właściwości instancji. Oto kod pseudo:Typ dynamiczny rzutowania z id do klasy w celu c

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

NSNumber *latitude = obj.latitude; 

Następnie kompilator mówi mi, co następuje: własność „szerokości geograficznej” nie znaleziono obiektu typu „__strong id”

Albo Class1 i Class2 to główne podmioty danych i mają prawie ten sam rodzaj atrybutów. W warunkach1 _fetchedResults zwraca obiekty typu Class1 i condition2 _fetchedResults zwraca obiekty typu Class2.

Czy ktoś mógłby dać mi wskazówkę, jak rozwiązać ten problem?

Dzięki!

+0

Myślę, że powinieneś najpierw upewnić się, że to, co zwraca [_fetchedResults objectAtIndex: indexPath.row], jest klasą ma właściwość szerokość geograficzna. Również rzutowanie typu NSManagedObject na typ NSManagedObject jest również niepoprawne. Potrzebujesz NSManagedObjectContext za każdym razem i jakkolwiek tworzysz instancję NSManagedObject. –

Odpowiedz

4

można uzyskać dostęp do właściwości poprzez klucz-wartość Coding (KVC):

[obj valueForKey:@"latitude"] 
+0

Zauważ, że używanie KVC do tego pozbawia Cię wszelkich kontroli typów z kompilatora. – ipmcc

+3

@ipmcc Oczywiście, ale tak samo jak "id" w pierwszej kolejności :-) – Monolo

+0

@Monolo Jest to niepotrzebne i ma taki sam efekt jak [obj szerokość geograficzna] – hooleyhoop

1

Zmienna obj musi być typu, który ma właściwość w pytaniu. Jeśli obie jednostki mają tę samą właściwość, jednym ze sposobów osiągnięcia tego byłoby zadeklarowanie właściwości we wspólnej klasie bazowej. Jeśli to nie jest odpowiednie dla tych dwóch typów dzielić wspólną klasę bazową, a następnie można je przyjąć wspólny protokół, na przykład:

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

@interface Class1 (AdoptLatitudeHaving) <LatitudeHaving> 
@end 

@interface Class2 (AdoptLatitudeHaving) <LatitudeHaving> 
@end 

Stamtąd będzie można zadeklarować obj jako takie id<LatitutdeHaving> coś takiego:

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

NSNumber *latitude = obj.latitude; 

I to powinno wystarczyć. FWIW, protokoły są podobne do interfejsów w Javie.

+0

Jakie są odlewy Class1 * i Class2 *? – hooleyhoop

+0

'objectAtIndex:' zwraca "id", a nie "id ". Te odlewania mogą nie być bezwzględnie konieczne, aby uniknąć skarg kompilatora, ale próbowałem uczynić kod tak blisko kodu OP, jak to tylko możliwe. – ipmcc