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 и оба являются кластерами классов, у меня возникают проблемы с их сортировкой.

So:

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

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

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


person drekka    schedule 13.09.2016    source источник


Ответы (2)


Что о:

-(void) doSomethingWith:(id) value {
    if ([value isKindOfClass:[NSValue class]] && ![value isKindOfClass:[NSNumber class]]) {
       // NSValue but not instance of NSNumber
    } else {
       ...
    }
}
person Codo    schedule 13.09.2016
comment
Спасибо. Я тоже остановился на этом решении. :-) Немного некрасиво, но работает. - person drekka; 14.09.2016

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

isKindOfClass

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

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

isMemberOfClass

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

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

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

NSValue

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

NSNumber

NSNumber — это подкласс NSValue, который предлагает значение любого скалярного (числового) типа C. Он определяет набор методов специально для установки и доступа к значению как знаковый или беззнаковый char, короткий 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
{
   ......... 
}

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

person user3182143    schedule 13.09.2016