views:

54

answers:

1

In summary, I am having a problem where I read what I expect to be an NSNumber from an NSArray contained in a property list and instead of getting a number such as '1', I get what looks to be a memory address (i.e. '61879840'). The numbers are clearly correct in the property list. Anyone know why this may be happening and what I can do to fix it?

Below is my process for creating the property list and reading it back.

Creating the property list

I have created a simple Objective-C property list with arrays of integers within one root array:

<array>
  <array>
    <integer>1</integer>
    <integer>2</integer>
  </array>
  <array>
    <integer>1</integer>
    <integer>2</integer>
    <integer>5</integer>
  </array>
  ... more arrays with integers ...
</array>

The arrays are NSArray objects and the integers are NSNumber objects. The property list has been created and serialized using the following code:

// factorArray is an NSArray that contains NSArrays of NSNumbers as described above
// serialize and compress factorArray as a property list, Factors-bin.plist
NSString *error;
NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                        NSUserDomainMask, YES)
                      objectAtIndex:0];
NSString *plistPath = [rootPath stringByAppendingPathComponent:@"Factors-bin.plist"];
NSData *plistData = [NSPropertyListSerialization
                     dataFromPropertyList:factorArray
                     format:NSPropertyListBinaryFormat_v1_0
                     errorDescription:&error];

Inspecting the created plist, all values and types are correct, leading me to believe that I've properly created the list.

Reading the property list

The property list is read in as Data and then converted to an NSArray:

NSString *path = [[NSBundle mainBundle] pathForResource:@"Factors" ofType:@"plist"];
NSData *plistData = [[NSData alloc] initWithContentsOfFile:path];
NSPropertyListFormat format;
NSString *error = nil;
NSArray *factorData = (NSArray *)[NSPropertyListSerialization
                                  propertyListFromData:plistData
                                  mutabilityOption:NSPropertyListImmutable
                                  format:&format
                                  errorDescription:&error];

Cycling through factorData to see what it contains is where I see the erroneous integers:

for (int i = 0; i < 10; i++) {
  NSArray *factorList = (NSArray *)[factorData objectAtIndex:i];
  NSLog(@"Factors of %d\n", i + 1);
  for (int j = 0; j < [factorList count]; j++) {
    NSLog(@"  %d\n", (NSNumber *)[factorList objectAtIndex:j]);
  }
}

I see all the correct number of values, but the values themselves are incorrect, i.e.:

Factors of 3
  61879840 (should be 1)
  61961200 (should be 3)
Factors of 4
  61879840 (should be 1)
  61943472 (should be 2)
  61943632 (should be 4)
Factors of 5
  61879840 (should be 1)
  61943616 (should be 5)
+1  A: 

Try logging the intValue of the NSNumber instead:

NSLog(@"  %d\n", [(NSNumber *)[factorList objectAtIndex:j] intValue]);
DyingCactus
Wow. That totally worked - thanks very much! I guess reading some documentation on NSNumber, I thought it acted as an integer. Rookie mistake!
Gaurav
NSNumber is an object wrapper for primitive types so NSNumber by itself is just an object reference. You have to get the primitive value inside it.
DyingCactus
@Gaurav: You could also have printed the NSNumber object itself with `NSLog(@"%@", [factorList objectAtIndex:j])`, which would achieve the same goal.
Chuck