Utwórz podklasę klasy używającej init rodzica - z innej klasy
Edytuj: Ten syndrom downvoting tutaj jest do dupy. Zadałem pytanie, w którym moim zdaniem pokazałem, że odrobiłem pracę domową i poprosiłem o radę. Odpowiedzi upvoted sugerowały przechodzenie z ostrzeżeniami dotyczącymi czasu kompilacji, podczas gdy moja własna i prawdopodobnie najczystsza metoda OOP nie była zainteresowana.
Krótki przegląd, aby zrozumieć, dlaczego potrzebuję tego i co próbuję zrobić: Piszę ORM, który implementuje wzorzec mapowania danych. Mapper (tj. Dla wyników SQLite) musi tworzyć podklasy klasy encji - używając inicjatora klasy jednostki podstawowej. Więc jest problem.
Mapper nie wie i nie powinien wiedzieć o konkretnych klasach. Opisy mapowania i określone programy odwzorowujące dla różnych źródeł danych są wyodrębniane z klasy encji i według części projektu opisu jednostki.
Elementy są podobne do NSManagedObject, chociaż ORM ma inny wzór. Opis, w którym tworzona jest dowolna jednostka, jest podobny do opisu NSEntityDescription (ale także zgodny z innym wzorem i celem).
Tak więc moim celem jest stworzenie obiektów, które znam, są podklasami ManagedEntity, przy użyciu metody init ManagedEntity.
Tak więc init mojego mapera wygląda tak:
- (id)initWithEntityClass:(Class)EntityClass entityDescriptor:(EntityDescription*)entityDescriptor
{
self = [super init];
if (self)
{
_EntityClass = EntityClass;
_entityDescription = entityDescription;
... (assert that class is of subclass of ManagedEntity)
}
A jakiś czas później w moim programie mapującym chcę stworzyć konkretną jednostkę:
-(void)createEntityWithSQLiteResultSet:(sqlite3_stmt*)resultSet
{
// Problem: How to init a class known to be a subclass of ManagedEntity?
ManagedEntity *newEntity = [[_EntityClass] alloc] initWithEntityDescription:_entityDescription];
}
Jak więc utworzyć tę klasę potomną ManagedEntity, używając init of ManagedEntity?
Oczywiście, mogłem użyć respondsToSelector () dla initWithEntityDescription i wywołać to. Ale coś mi mówi, że powinien istnieć bardziej elegancki sposób, w którym rodzaj klasy jest już znany. Ponadto wywołanie respondsToSelector i selektor wykona tylko sprawdzanie środowiska wykonawczego. Nawet jeśli inicjator encji nie powinien się zmienić, wydaje się złym wyborem, aby stracić czas kompilacji, sprawdzając, czy ta metoda istnieje.