2

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;

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

user7865437
  • 812
  • 14
  • 28

3 Answers3

1

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> *.

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • how about abstract entities and setting the parent entity in the xcdatamodel. – Joe Jul 01 '11 at 15:22
  • I think I was not seeing the wood for the trees! I need to make 7 calls to populate the tables and fell into the trap of 7 tables (been a while since any real DB work) and it was not until I starting to answer the comments made to my question that the light came on and I could see the error of my ways!! Thanks for all feedback folks, appreciated – user7865437 Jul 01 '11 at 19:45
0

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.

Alex
  • 8,801
  • 5
  • 27
  • 31
  • The only problem there is 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. Your method would work but I would have lots of repeating lines of code :-( – user7865437 Jul 01 '11 at 13:55
  • 4
    Mmmm I am just asking myself...why "I have 7 different entities all with identical fields" why not one entity with a flag field denoting type! – user7865437 Jul 01 '11 at 14:02
0

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

daveoncode
  • 18,900
  • 15
  • 104
  • 159