编辑:这里的这种投票综合症很糟糕。我问了一个问题,我认为我做了功课,并征求意见。赞成的答案暗示了编译时警告,而我自己的,可能是最干净的 OOP 方式没有引起任何兴趣。
简要概述以了解我为什么需要它以及我尝试做什么:我正在编写一个实现数据映射器模式的 ORM。映射器(即用于 SQLite 结果)必须创建实体类的子类 - 使用基实体类的初始化程序。所以有问题。
映射器不知道也不应该知道特定的类。不同数据源的映射描述和特定映射器从实体类中抽象出来,并且是实体描述的设计部分。
实体类似于 NSManagedObject,尽管 ORM 遵循不同的模式。创建任何实体的描述类似于 NSEntityDescription(但也遵循不同的模式和目的)。
所以我的目标是使用 ManagedEntity 的 init 方法创建我知道是 ManagedEntity 子类的实体。
所以我的映射器的 init 看起来像这样:
- (id)initWithEntityClass:(Class)EntityClass entityDescriptor:(EntityDescription*)entityDescriptor
{
self = [super init];
if (self)
{
_EntityClass = EntityClass;
_entityDescription = entityDescription;
... (assert that class is of subclass of ManagedEntity)
}
稍后在我的映射器中,我想创建具体实体:
-(void)createEntityWithSQLiteResultSet:(sqlite3_stmt*)resultSet
{
// Problem: How to init a class known to be a subclass of ManagedEntity?
ManagedEntity *newEntity = [[_EntityClass] alloc] initWithEntityDescription:_entityDescription];
}
那么如何使用 ManagedEntity 的 init 创建 ManagedEntity 的这个子类呢?
当然,我可以将 respondsToSelector() 用于 initWithEntityDescription 并调用它。但是有些事情告诉我应该有一种更优雅的方式,其中类类型已经知道。此外,respondsToSelector 和选择器调用将只进行运行时检查。即使实体初始化程序不应该改变,如果这个方法存在,失去编译时间检查似乎是一个糟糕的选择。