Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic type cast from id to class in objective c

I would like to cast dynamically in Objective C and access instance properties. Here a pseudo code:

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

NSNumber *latitude = obj.latitude;

Then the compiler tells me the following: property 'latitude' not found on object of type '__strong id'

Either Class1 and Class2 are core data entities and have nearly the same kind of attributes. In condition1 _fetchedResults returns objects of type Class1 and in condition2 _fetchedResults returns objects of type Class2.

Could someone give me a hint how to solve this kind of problem?

Thanks!

like image 423
DoK Avatar asked Apr 30 '13 11:04

DoK


People also ask

How do you type cast in Objective-C?

Type conversions can be implicit which is performed by the compiler automatically or it can be specified explicitly through the use of the cast operator. It is considered good programming practice to use the cast operator whenever type conversions are necessary.

What does @() mean in Objective-C?

In Objective-C, any character , numeric or boolean literal prefixed with the '@' character will evaluate to a pointer to an NSNumber object (In this case), initialized with that value. C's type suffixes may be used to control the size of numeric literals. '@' is used a lot in the objective-C world.

What is ID type in Objective-C?

“id” is a data type of object identifiers in Objective-C, which can be use for an object of any type no matter what class does it have. “id” is the final supertype of all objects.


2 Answers

You can access the properties through Key-Value Coding (KVC):

[obj valueForKey:@"latitude"]
like image 94
Monolo Avatar answered Nov 09 '22 18:11

Monolo


The obj variable needs to be of a type that has the property in question. If both entities have the same property, one way to achieve this would be for the property to be declared on a common base class. If it's not appropriate for these two types to share a common base class, then you could have them adopt a common protocol, like this:

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

@interface Class1 (AdoptLatitudeHaving) <LatitudeHaving>
@end

@interface Class2 (AdoptLatitudeHaving) <LatitudeHaving>
@end

From there, you would declare obj as being an id<LatitutdeHaving>, like this:

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

NSNumber *latitude = obj.latitude;

And that should do it. FWIW, protocols are similar to Interfaces in Java.

like image 43
ipmcc Avatar answered Nov 09 '22 19:11

ipmcc