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

Posted

技术标签:

【中文标题】在运行时将类型 id 的对象转换为未知类型【英文标题】:casting object of type id to to an unknown type at runtime 【发布时间】:2011-07-01 13:20:01 【问题描述】:

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

这里我有实体作为 id,我试图将其设置为需要的对象类型,以准备调用插入行。

问题是当我调用 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];

我哪里错了?

谢谢

【问题讨论】:

【参考方案1】:

我有 7 个不同的实体,它们都具有相同的字段,因此我尝试将所需的实体类动态分配给“实体”,因此在我的循环中,我将只有一行使用 NSEntityDescription 属性设置。

嗯,您已经想到“为什么不使用一个带有表示类型的标志字段的实体?”,这是一个很好的问题,我非常建议您采用这条路线。

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

【讨论】:

抽象实体和在 xcdatamodel 中设置父实体怎么样。 我想我没有只见树木不见森林!我需要打 7 个电话来填充表格并陷入 7 个表格的陷阱(自从任何真正的数据库工作以来已经有一段时间了),直到我开始回答对我的问题提出的 cmets,灯亮了,我可以看到我的方式的错误!感谢所有反馈的人,感谢【参考方案2】:

你为什么不创建一个 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.");

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

【讨论】:

唯一的问题是我有 7 个不同的实体,它们都具有相同的字段,所以我试图将所需的实体类动态分配给“实体”,所以在我的循环中我只有一行使用 NSEntityDescription 和属性设置。你的方法可行,但我会有很多重复的代码行:-( 嗯,我只是在问自己......为什么“我有 7 个不同的实体都具有相同的字段”为什么没有一个实体具有表示类型的标志字段!【参考方案3】:

我不是专家,但据我所知,声明变量的方法只有两种:

    使用静态类型(当您声明变量的类型时:UIView *myview) 使用动态类型(当您使用“id”声明变量时:id myObject)

在第一种情况下,类型在编译时是已知的,编译器将执行一系列检查以确保代码的一致性。 在第二种情况下,直到运行时才知道类型。 无论如何,一旦定义了变量的类型(使用 id 或特定的类名),就无法重新定义它。

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

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

【讨论】:

以上是关于在运行时将类型 id 的对象转换为未知类型的主要内容,如果未能解决你的问题,请参考以下文章

Java多态对象的类型转换和动态绑定

将 JSON 对象脱盐到数据表时将值“1D”转换为类型“System.Int64”时出错

面向对象----多态类型的转换

C# 在运行时将 Enumerable.Iterator 强制转换为已知 List<Object>

在C#中,您可以将对象类型向上转换为通用“对象”的集合类型

oc 中的id类型与类型转换