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:
- using static typing (when you declare the type of your variable: UIView *myview)
- 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
精彩评论