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
Возвращает логическое значение, которое указывает, является ли получатель экземпляром данного класса или экземпляром какого-либо класса, который наследуется от этого класса.
ДА, если получатель является экземпляром aClass или экземпляром любого класса, который наследуется от aClass, в противном случае НЕТ.
Возвращает логическое значение, которое указывает, является ли получатель экземпляром данного класса.
ДА, если получатель является экземпляром класса, в противном случае НЕТ.
Тогда очень важно
NSValue объект представляет собой простой контейнер для одного элемента данных C или Objective-C. Он может содержать любой из скалярных типов, таких как int, float и char, а также указатели, структуры и ссылки на идентификаторы объектов. Используйте этот класс для работы с такими типами данных в коллекциях (таких как NSArray и NSSet), кодировании значения ключа и других API, для которых требуются объекты Objective-C. NSValue объекты всегда неизменны.
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
{
.........
}
Объекты класса могут быть объектами, созданными компилятором, но они все еще поддерживают концепцию членства. Таким образом, вы можете использовать этот метод для проверки того, что получатель является конкретным объектом класса.