ObjC: различие между NSValue и NSNumber

У меня есть код, где я буду получать объект неизвестного типа. Это может быть NSString, NSNumberскаляр, завернутый в NSValue или какой-то другой класс:

-(void) doSomethingWith:(id) value {
    if ( <test-for-NSValue> ) { 
        // Do something with a NSValue
    } else {
        // Do something else
    }
}

Мне нужно определить, где находится скалярный тип внутри NSValue.

Проблема заключается в том, чтобы определить скаляр NSValue по сравнению с NSNumber. Поскольку NSNumber наследуется от NSValue, и оба являются кластерами классов, я не могу разобраться с ними.

Так:

[value isKindOfClass:[NSValue class]]... видит NSNumbers как NSValues.

[value isMemberOfClass:[NSValue class]]... не распознает NSValues, потому что экземпляры являются конкретными подтипами.

У кого-нибудь есть идеи, как это сделать?

2 ответа

Решение

Как насчет:

-(void) doSomethingWith:(id) value {
    if ([value isKindOfClass:[NSValue class]] && ![value isKindOfClass:[NSNumber class]]) {
       // NSValue but not instance of NSNumber
    } else {
       ...
    }
}

Сначала нам нужно о разнице между iskindofClass и isMemberOfClass

isKindOfClass

Возвращает логическое значение, которое указывает, является ли получатель экземпляром данного класса или экземпляром какого-либо класса, который наследуется от этого класса.

ДА, если получатель является экземпляром aClass или экземпляром любого класса, который наследуется от aClass, в противном случае НЕТ.

isMemberOfClass

Возвращает логическое значение, которое указывает, является ли получатель экземпляром данного класса.

ДА, если получатель является экземпляром класса, в противном случае НЕТ.

Тогда очень важно

NSValue

NSValue объект представляет собой простой контейнер для одного элемента данных C или Objective-C. Он может содержать любой из скалярных типов, таких как int, float и char, а также указатели, структуры и ссылки на идентификаторы объектов. Используйте этот класс для работы с такими типами данных в коллекциях (таких как NSArray и NSSet), кодировании значения ключа и других API, для которых требуются объекты Objective-C. NSValue объекты всегда неизменны.

NSNumber

NSNumber - это подкласс NSValue, который предлагает значение в качестве любого скалярного (числового) типа Си. Он определяет набор методов, специально предназначенных для установки и доступа к значению как знаковый или беззнаковый символ, short int, int, long int, long long int, float или double или как BOOL. (Обратите внимание, что числовые объекты не обязательно сохраняют тип, с которым они созданы.) Он также определяет метод compare: для определения порядка двух объектов NSNumber.

if ([value isKindOfClass:[NSValue class]]) //It will return YES because NSNumber value subclass or inherits from NSValue
{
   ..........
}

if ([value isMemberOfClass:[NSValue class]])  //It will return NO because NSNumber value is not a member of the NSValue
{
   ......... 
}

Объекты класса могут быть объектами, созданными компилятором, но они все еще поддерживают концепцию членства. Таким образом, вы можете использовать этот метод для проверки того, что получатель является конкретным объектом класса.

Другие вопросы по тегам