使用父级的init创建类的子类-来自另一个类 [英] Create a subclass of a class using parent's init - from another class

查看:98
本文介绍了使用父级的init创建类的子类-来自另一个类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里的投票结果糟糕透顶.我问了一个问题,我认为这表明我做了作业,并征求了意见.赞成的答案暗示会附带编译时警告,而我自己的,也可能是最干净的OOP方法并没有引起任何兴趣.

简要概述,以了解为什么我需要这样做以及我想做的事情:我正在编写一个实现数据映射器模式的ORM.映射器(即用于SQLite结果的映射器)必须使用基本实体类的初始化程序创建实体类的子类.所以有问题.

Brief overview in order to understand why I need this and what I try to do: I'm writing an ORM that implements the data mapper pattern. A mapper (i.e. for SQLite results) must create subclasses of an entity class - using the initializer of the base entity class. So there is the problem.

映射器不知道,也不应该知道特定的类.对于不同数据源的映射描述和特定的映射器是从实体类中抽象出来的,并通过设计来设计实体描述的一部分.

The mapper does not, and should not, know about specific classes. Mapping descriptions and specific mappers for different data sources are abstracted away from the entity class, and by design part of the entity description.

实体类似于NSManagedObject,尽管ORM遵循不同的模式.创建任何实体的描述都类似于NSEntityDescription(但也遵循不同的模式和目的).

Entities are similar to NSManagedObject, though the ORM follows a different pattern. The description any entity is created with is similar to NSEntityDescription (but also following a different pattern and purpose).

所以我的目标是使用ManagedEntity的init方法创建我知道是ManagedEntity的子类的实体.

So my goal is to create entities that I know are subclasses of ManagedEntity, using the init method of ManagedEntity.

所以我的映射器的初始化看起来像这样:

So the init of my mapper looks like this:

- (id)initWithEntityClass:(Class)EntityClass entityDescriptor:(EntityDescription*)entityDescriptor
{
self = [super init];
if (self)
{
    _EntityClass = EntityClass; 
    _entityDescription = entityDescription;

    ... (assert that class is of subclass of ManagedEntity)
}

一段时间后,我想在映射器中创建具体实体:

And some time later in my mapper I then want to create the concrete entity:

-(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的子类?

So how do I create this child class of ManagedEntity, using the init of ManagedEntity?

当然,我可以将responsesToSelector()用于initWithEntityDescription并调用它.但是有一些事情告诉我,应该有一种更优雅的方式来知道此类.另外,responsToSelector和选择器调用将仅执行运行时检查.即使实体初始值设定项不应该更改,但丢失检查这种方法是否存在的编译时间似乎也是一个错误的选择.

Sure, I could use respondsToSelector() for initWithEntityDescription and invoke that. But something tells me there should be a more elegant way where the class kind is already known. Also, respondsToSelector and selector invocation will do a runtime check only. Even though the entity initializer should not change, it seems a bad choice to lose compile time checking if this method exists.

推荐答案

作为映射的一部分,您必须知道所需的子类.然后使用

As part of your mapping, you must know what subclass you need. Then use

ManagedEntity *newEntity = [[NSClassFromString(className) alloc] initWithEntityDescription:_entityDescription];

正如我所承诺的那样,我在GitHub项目中进行了构建,并意识到了为什么它可能无法编译.您必须在作用域内可访问的已知类中声明-initWithEntityDescription:.在这种情况下,这意味着您必须声明并实现ManagedEntity -initWithEntityDescription:,并在文件顶部具有#import"ManagedEntity.h".

I was building out this in a GitHub project as I promised and realized why it may not compile. You must have -initWithEntityDescription: declared in a known class that is accessible within the scope. In this case, it would mean that you must declare and implement ManagedEntity -initWithEntityDescription: and have have `#import "ManagedEntity.h" at the top of your file.

这篇关于使用父级的init创建类的子类-来自另一个类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆