objective-cintjsonmodelnsuinteger

Questions about NSUinteger and int


I use JSONModel to capture data from json:

@interface BBTCampusBus : JSONModel

@property (strong, nonatomic) NSString * Name;
@property (assign, nonatomic) NSUInteger Latitude;
@property (assign, nonatomic) NSUInteger Longitude;
@property (nonatomic)         BOOL       Direction;
@property (assign, nonatomic) NSUInteger Time;
@property (nonatomic)         BOOL       Stop;
@property (strong, nonatomic) NSString * Station;
@property (assign, nonatomic) NSInteger  StationIndex;
@property (assign, nonatomic) NSUInteger Percent;
@property (nonatomic)         BOOL       Fly;

@end

And I have the following code:

for (int i = 0;i < [self.campusBusArray count];i++)
{
    NSLog(@"index at nsuinteger - %@", (NSUInteger)self.campusBusArray[i][@"StationIndex"]);
    NSLog(@"index - %lu", index);
    if ([(NSUInteger)self.campusBusArray[i][[@"StationIndex"] ]== index)
    {
        numberOfBusesCurrentlyAtThisStation++;
    }
}

Actually StationIndex is a 1 or 2 digit integer. For example I have self.campusBusArray[i][@"StationIndex"] == 4, and I have index == 4, then the two NSLog all output 4, but it will not jump into the if block, or the numberOfBusesCurrentlyAtThisStation++ won't be executed. Can somebody tell my why?


Solution

  • Lets look at the line:

    NSLog(@"index at nsuinteger - %@", (NSUInteger)self.campusBusArray[i][@"StationIndex"]);
    

    %@ says that an object will be included in the log, one that implements description. That's good, because the end of the expression dereferences a dictionary, which may only contain objects.

    NSUInteger, like int is a scalar type. Like old-fashioned C, its just a group of bytes in memory whose value is the numerical value of those bytes. An object, even one that represents a number, like NSNumber cannot be cast using the c-style cast (moreover, the precedence of the cast is low, this expression really just casts self, also nonsensical).

    So it appears that self.campusBusArray is an array of dictionaries (probably the result of parsing JSON describing an array of objects). And it appears you expect those dictionaries to have a key called [@"StationIndex"] with a numerical value. That must be an NSNumber by the rules of objective-c collections (they hold objects). Therefore:

    NSDictionary *aCampusBusObject = self.campusBusArray[i];     // notice no cast
    NSNumber *stationIndex = aCampusBusObject[@"StationIndex"];  // this is an object
    NSUInteger stationIndexAsInteger = [stationIndex intValue];  // this is a simple, scalar integer
    
    if (stationIndexAsInteger == 4) {  // this makes sense
    }
    
    if (stationIndex == 4) {  // this makes no sense
    }
    

    That last line tests to see of the pointer to an object (an address in memory) is equal to 4. Doing scalar math on, or casts on, or comparisons on object pointers almost never makes sense.

    Rewriting...

    for (int i = 0;i < [self.campusBusArray count];i++)
    {
        NSDictionary *aCampusBusObject = self.campusBusArray[i];
        NSNumber *stationIndex = aCampusBusObject[@"StationIndex"];
        NSUInteger stationIndexAsInteger = [stationIndex intValue];
    
        NSLog(@"index at nsuinteger - %lu", stationIndexAsInteger);
        NSLog(@"index - %lu", index);
        if (stationIndexAsInteger == index)
        {
            numberOfBusesCurrentlyAtThisStation++;
        }
    }