Search code examples
objective-cstructnsmutablearraynsvalue

NSMutableArray: add and extract struct


I'm trying to store some data in an NSMutableArray. This is my struct:

typedef struct{
    int time;
    char name[15];
}person;

This is the code to add a person:

person h1;
h1.time = 108000;
strcpy(h1.name, "Anonymous");
[highscore insertObject:[NSValue value:&h1 withObjCType:@encode(person)] atIndex:0];

So, I try to extract in this way:

NSValue * value = [highscore objectAtIndex:0];
person p;
[value getValue:&p];
NSLog(@"%d", p.time);

The problem is that the final log doesn't show me 108000!
What is wrong?


Solution

  • As stated in my initial comment there rarely is a reason to do this kind of stuff with pure c structs. Instead go with real class objects:

    If you're unfamiliar with the syntax below you may want to look at these quick tutorials on ObjC 2.0 as well as read Apple's documentation:

    Person Class:

    // "Person.h":
    @interface Person : NSObject {}
    
    @property (readwrite, strong, nonatomic) NSString *name;
    @property (readwrite, assign, nonatomic) NSUInteger time; 
    
    @end
    
    // "Person.m":
    @implementation Person
    
    @synthesize name = _name; // creates -(NSString *)name and -(void)setName:(NSString *)name
    @synthesize time = _time; // creates -(NSUInteger)time and -(void)setTime:(NSUInteger)time
    
    @end
    

    Class use:

    #import "Person.h"
    
    //Store in highscore:
    
    Person *person = [[Person alloc] init];
    person.time = 108000; // equivalent to: [person setTime:108000];
    person.name = @"Anonymous"; // equivalent to: [person setName:@"Anonymous"];
    [highscore insertObject:person atIndex:0];
    
    //Retreive from highscore:
    
    Person *person = [highscore objectAtIndex:0]; // or in modern ObjC: highscore[0];
    NSLog(@"%@: %lu", person.name, person.time);
    // Result: "Anonymous: 108000"
    

    To simplify debugging you may also want Person to implement the description method:

    - (NSString *)description {
        return [NSString stringWithFormat:@"<%@ %p name:\"%@\" time:%lu>", [self class], self, self.name, self.time];
    }
    

    which will allow you to just do this for logging:

    NSLog(@"%@", person);
    // Result: "<Person 0x123456789 name:"Anonymous" time:108000>