3

I have some code where I will be receiving an object of unknown type. It could be a NSString, NSNumber, a scalar wrapped in a NSValue or some other class:

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

I need to identify where there is a scalar type inside a NSValue.

The problem is identifying a NSValue wrapped scalar vs a NSNumber. As NSNumber inherits from NSValue and both are class clusters, I'm haing trouble sorting them out.

So:

[value isKindOfClass:[NSValue class]] ... sees NSNumbers as NSValues.

[value isMemberOfClass:[NSValue class]] ... doesn't recognise NSValues because the instances are concrete subtypes.

Anyone got any idea how to do this?

drekka
  • 20,957
  • 14
  • 79
  • 135

2 Answers2

3

first we need about the diffrenciation between iskindofClass and isMemberOfClass

isKindOfClass

Returns a Boolean value that indicates whether the receiver is an instance of given class or an instance of any class that inherits from that class.

YES if the receiver is an instance of aClass or an instance of any class that inherits from aClass, otherwise NO.

isMemberOfClass

Returns a Boolean value that indicates whether the receiver is an instance of a given class.

YES if the receiver is an instance of aClass, otherwise NO.

Then very importantly

NSValue

An NSValue object is a simple container for a single C or Objective-C data item. It can hold any of the scalar types such as int, float, and char, as well as pointers, structures, and object id references. Use this class to work with such data types in collections (such as NSArray and NSSet), key-value coding, and other APIs that require Objective-C objects. NSValue objects are always immutable.

NSNumber

NSNumber is a subclass of NSValue that offers a value as any C scalar (numeric) type. It defines a set of methods specifically for setting and accessing the value as a signed or unsigned char, short int, int, long int, long long int, float, or double or as a BOOL. (Note that number objects do not necessarily preserve the type they are created with.) It also defines a compare: method to determine the ordering of two NSNumber objects

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 objects may be compiler-created objects but they still support the concept of membership. Thus, you can use this method to verify that the receiver is a specific Class object.

user3182143
  • 9,459
  • 3
  • 32
  • 39
1

What about:

-(void) doSomethingWith:(id) value {
    if ([value isKindOfClass:[NSValue class]] && ![value isKindOfClass:[NSNumber class]]) {
       // NSValue but not instance of NSNumber
    } else {
       ...
    }
}
Codo
  • 75,595
  • 17
  • 168
  • 206