在运行时将类型为id的对象转换为未知类型

时间:2011-07-01 13:20:02

标签: iphone casting nsentitydescription

我有一个方法,它将我的sqlite数据库中的实体名称作为字符串,我试图简化为尽可能少的重复代码。

这里我将实体作为id,我试图设置为require对象类型,以便调用插入一行。

问题是当我调用NSEntityDescription实体时仍然是类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];

我哪里错了?

由于

3 个答案:

答案 0 :(得分:1)

  

我有7个不同的实体都具有相同的字段,所以我试图动态地将所需的实体类分配给'entity',所以在我的循环中我只有一行使用NSEntityDescription属性设置。

嗯,你已经想到了“为什么一个标志字段表示类型的实体?”,这是一个很好的问题,我非常建议你选择这条路线。

如果由于某种原因,您不能,则可以在协议中声明相同的字段,然后声明这7个实体都符合相同的协议。在您的方法中,您的类型声明将是(而不是id):NSManagedObject<MyCustomProtocol> *

答案 1 :(得分:0)

为什么不创建typedef:

typedef enum {

EntityTypeYaddaYadda,
EntityTypeBlahBlah,
    EntityTypeFoobar

} EntityType;

然后执行开关:

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;
}

然后保存您的上下文:

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

有时需要重复一点代码才能使其可读和可扩展。

答案 2 :(得分:0)

我不是大师,但据我所知,只有两种方式来声明变量:

  1. 使用静态类型(当您声明变量的类型时:UIView * myview)
  2. 使用动态类型(当您使用“id”声明变量时:id myObject)
  3. 在第一种情况下,在编译时知道类型,编译器将执行一系列检查以确保代码中的一致性。 在第二种情况下,直到运行时才知道类型。 无论如何,一旦定义了变量的类型(使用 id 或特定的类名),就无法重新定义它。

    无论如何,您可以使用 NSSClassFromString()动态分配类,避免使用if / else或switch语句。

    此外,您可以(应该)使用respondsToSelector:(SEL)等工具来确保您安全地向班级发送消息