2011-01-06 4 views
4

В интерфейсе у меня есть это:Objective C - определить тип класса во время выполнения

Animal*  myPet; 

Во время выполнения я могу хотеть myPet быть кошка или собака, которые являются подклассами животных:

id newPet; 
    if(someCondition) { 
      newPet = [[Cat alloc] initWithNibName:@"Cat" bundle:nil]; 
    } else { 
      newPet = [[Dog alloc] initWithNibName:@"Dog" bundle:nil]; 
    } 
    self.myPet = newPet; 

Очевидно, это неверно, но я надеюсь, что этого достаточно, чтобы показать, что я пытаюсь сделать. Какова наилучшая практика для этого?

+3

И почему вы сказали это неправильно? –

+2

Обратите внимание, что выполнение большого количества 'isKindOfClass:' в вашем коде обычно является признаком того, что вы делаете что-то трудное. – bbum

+0

@Dave - Потому что он не работает. Если я попробую newPet.hunger = 50, я получаю ошибку: запрос для члена 'hunger' в 'newPet', который относится к классу non-class 'objc_object *' – sol

ответ

8

Прочный тип newPet как Animal * вместо id. id может содержать ссылку на экземпляр любого класса, но свойства не могут быть использованы с ним (для точечного синтаксиса требуется строго типизированное значение lvalue.) Поскольку оба значения Cat инаследуют от Animal, это будет совершенно корректно и корректно.

Если вы используете два класса, которые сделать не доли общего предка (в прошлом NSObject), то вы должны сделать шаг назад и пересмотреть свой дизайн - почему бы экземпляры этих двух классов должны занимать такая же переменная?

9

isKindOfClass ваш друг:

[newPet isKindOfClass:Dog.class] == NO 
+0

Я понимаю isKindOfClass, но я не уверен, как он вписывается в мой примерный код. Я не пытаюсь определить, какой класс является Animal, я пытаюсь создать различные виды Животные, основанные на someCondition. – sol

+0

@sol: это «someCondition», которое вы ищете, именно то, что выложил The-Kenny (т. Е. '[NewPet isKindOfClass: Dog.class] == NO'). – Senseful

3
NSString *className = @"Cat"; 
Animal *myPet = [[NSClassFromString(className) alloc] init]; 

Неясно, что вы после этого, но если вы хотите создать экземпляр класса с именем строкой, это должно сделать это.

2

Для тех, кто приезжая из Google на основе заглавия: «Определить тип класса во время выполнения», вот некоторые полезные вещи, чтобы знать:

Вы можете вызвать class метод на NSObject* во время выполнения, чтобы получить ссылку к его классу.

[myObject class]; 

Взгляните на эти методы тоже:

  • isKindOfClass: - проверить, если объект принадлежит к классу где-нибудь в своей иерархии.
  • isMemberOfClass: - проверить, принадлежит ли объект определенному классу.
Смежные вопросы