开发者

casting object of type id to to an unknown type at runtime

I have a method that takes as a string the name of an entity in my sqlite database that I am trying to streamline to use as little repeating code as possible.

here I have entity as id that I am trying to set to the require object type in readiness to make the call to insert a row.

problem is when I make the call to NSEntityDescription entity is still of class id

  id entity;开发者_StackOverflow社区

if ([entityName isEqualToString:@"yadda yadda"]) {

    entity = [EntityYadda class];
}
else if ([entityName isEqualToString:@"blah blah"]) {

    entity = [EntityBlah class];
}
else if ([entityName isEqualToString:@"Foobar"]) {

    entity = [EntityFoobar class];
}

for (int x=0; x<[data count]; x++) {

    entity = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context];

Where am I going wrong?

Thanks


I have 7 different entities all with identical fields so I am trying to dynamically assign the required entity class to 'entity' so in my loop I will have only one line using NSEntityDescription an property settings.

Well, you've already had the thought of "why not one entity with a flag field denoting type?", and that is an excellent question, and I would very much recommend going with that route.

If, for some reason, you cannot, you could declare the identical fields in a protocol, and then declare that these 7 entities all conform to the same protocol. In your method, your type declaration would be (instead of id): NSManagedObject<MyCustomProtocol> *.


Why don't you create a typedef:

typedef enum {

EntityTypeYaddaYadda,
EntityTypeBlahBlah,
    EntityTypeFoobar

} EntityType;

Then perform a switch:

for (int x=0; x<[data count]; x++) {

switch (entity.entityType){
case EntityTypeYaddaYadda:
{
YaddaYadda *yaddaYaddaObject = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context];
... set properties...
}
break;

case EntityTypeBlahBlah:
{
BlahBlah *blahBlahObject = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context];
... set properties...
}
break;

case EntityTypeFoobar:
{
Foobar *foobarObject = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context];
... set properties...
}
break;
}

Then save your context:

if (![managedObjectContext save:&error]) {
NSLog(@"Error while saving.");
}

Sometimes a little bit of code repetition is required to make it readable and expandable.


I'm not a guru, but as far I know, there are only 2 ways to declare variables:

  1. using static typing (when you declare the type of your variable: UIView *myview)
  2. using dynamic typing (when you declare your variable using "id": id myObject)

In the first case the type is know at compile time and the compiler will perform a series of check to ensure consistence in your code. In the second case the type is not know until at run time. Anyway once you define the type of a variable (using id or a specific class name), there is no way to redefine it.

You can anyway alloce classes dynamically using NSSClassFromString() avoiding long if/else or switch statement.

Moreover you can (should) use tools like respondsToSelector:(SEL) to ensure that you'll send a message to a class safely

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜