Як перевірити тип об'єкта в Objective-C?


557

Мені потрібно перевірити, чи є об’єкт типу NSStringчи UIImageView. Як я можу це досягти? Чи існує якийсь тип "ізотипового" методу?


32
Так, є:[object isKindOfClass:[ClassName class]]
Філіп Лейбаерт

Відповіді:


880

Якщо ваш об’єкт є 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в цьому випадку призведе до істинності обох разів, оскільки спадковий клас також є різновидом суперкласу.


3
isMemberOfClass:повернеться NOпри роботі з підкласами.
mipadi

11

Проводячи простий тест, я подумав, що я задокументую, що працює, а що ні. Часто я бачу людей, які перевіряють, чи є клас об'єкта членом іншого класу чи рівний іншому класу.

Для рядка внизу ми маємо деякі неякісні дані, які можуть бути an NSArray, an 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)) 

5

Простий [yourobject class] поверне ім'я класу yourobject.


1
Фактично це поверне Classоб’єкт. Однак, descriptionцим об'єктом буде ім'я класу у вигляді рядка, тому ви все одно можете ввійти до консолі.
devios1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.