В Objective-C, как я могу проверить тип объекта?

Ответы:

881

Если ваш объект есть myObject, и вы хотите проверить, является ли он NSString, код будет:

[myObject isKindOfClass:[NSString class]]

Точно так же, если вы хотите , чтобы проверить myObjectдля UIImageView:

[myObject isKindOfClass:[UIImageView class]]
ММС
источник
90
Обратите внимание, что есть также isMemberOfClass: метод, который проверяет класс «точность». Будьте осторожны с этим, поскольку многие объекты Apple на самом деле являются скрытыми типами Core Foundation. (Например, NSString чаще всего является NSCFString, а isMemberOfClass: возвращает сравнение для этого сравнения.)
Крейг Отис
3
Обратите внимание, что этот метод очень медленный!
SAKrisT
Это правильно, зная, что NSString является кластером классов? (как NSNumber)
Рикардо
52

Вы бы вероятно использовали

- (BOOL)isKindOfClass:(Class)aClass

Это метод NSObject.

Для получения дополнительной информации проверьте NSObjectдокументацию.

Вот как вы это используете.

BOOL test = [self isKindOfClass:[SomeClass class]];

Вы также можете попробовать сделать что-то подобное

for(id element in myArray)
{
    NSLog(@"=======================================");
    NSLog(@"Is of type: %@", [element className]);
    NSLog(@"Is of type NSString?: %@", ([[element className] isMemberOfClass:[NSString class]])? @"Yes" : @"No");
    NSLog(@"Is a kind of NSString: %@", ([[element classForCoder] isSubclassOfClass:[NSString class]])? @"Yes" : @"No");    
}
Брайан Хэйр
источник
4
-1: не используйте className, он может работать или не работать в OS X, но не в iOS и не предназначен для этого. Кроме того, NSLogони не делают то, что, как я думаю, вы имели в виду - они проверяют имя класса (всегда строка) и класс кодера, как ни странно, вместо класса фактического элемента.
andyvn22
5
Для быстрой проверки это: NSLog(@"Is of type: %@", [element class]); будет работать в iOS 7
Portland Runner
1
@PortlandRunner: Это именно то, что я искал. IDK, если есть билет, который адресован именно этой вещи, но если нет, вы должны создать его. Если вы это сделаете, я дам мне знать, и я буду приветствовать ответ там, так как этот фрагмент был сцеплением для меня. Еще раз спасибо.
Мэтт Уильямс
15

Если вы хотите различать суперкласс и унаследованный класс, вы можете использовать:

if([myTestClass class] == [myInheritedClass class]){
   NSLog(@"I'm the inheritedClass);
} 
if([myTestClass class] == [mySuperClass class]){
   NSLog(@"I'm the superClass);
} 

Использование - (BOOL)isKindOfClass:(Class)aClassв этом случае приведет к ИСТИНАМ оба раза, потому что наследованный класс также является разновидностью суперкласса.

Yedy
источник
3
isMemberOfClass:вернется NOпри работе с подклассами.
Mipadi
11

Запустив простой тест, я решил документировать, что работает, а что нет. Часто я вижу людей, проверяющих, является ли класс объекта членом другого класса или равен другому классу.

Для строки ниже у нас есть некоторые плохо сформированные данные, которые могут быть NSArray, NSDictionaryили (null).

NSArray *hits = [[[myXML objectForKey: @"Answer"] objectForKey: @"hits"] objectForKey: @"Hit"];

Это тесты, которые были выполнены:

NSLog(@"%@", [hits class]);

if ([hits isMemberOfClass:[NSMutableArray class]]) {
    NSLog(@"%@", [hits class]);
}

if ([hits isMemberOfClass:[NSMutableDictionary class]]) {
    NSLog(@"%@", [hits class]);
}

if ([hits isMemberOfClass:[NSArray class]]) {
    NSLog(@"%@", [hits class]);
}

if ([hits isMemberOfClass:[NSDictionary class]]) {
    NSLog(@"%@", [hits class]);
}

if ([hits isKindOfClass:[NSMutableDictionary class]]) {
    NSLog(@"%@", [hits class]);
}

if ([hits isKindOfClass:[NSDictionary class]]) {
    NSLog(@"%@", [hits class]);
}

if ([hits isKindOfClass:[NSArray class]]) {
    NSLog(@"%@", [hits class]);
}

if ([hits isKindOfClass:[NSMutableArray class]]) {
    NSLog(@"%@", [hits class]);
}

isKindOfClassработал довольно хорошо, пока isMemberOfClassнет.

Алекс Заватоне
источник
Я вижу, вы поделились кодом для тестов. Но где же напечатан результат?
nuynait
Идея в том, чтобы вы скопировали мой код и увидели результаты для того, что вам нужно.
Алекс Заватоне
9

Вы можете использовать следующий код, если хотите проверить типы примитивных типов данных.

// Returns 0 if the object type is equal to double
strcmp([myNumber objCType], @encode(double)) 
Bajju
источник
5

Просто, [класс yourobject] вернет имя класса вашего объекта.

AMohan
источник
1
На самом деле он вернет Classобъект. Однако, descriptionэтот объект будет именем класса в виде строки, поэтому вы все равно можете записать его в консоль.
devios1