What am I doing wrong with this NSMutableArray of structs in NSUserDefaults? "attempt to insert non-property list object"

StackOverflow https://stackoverflow.com/questions/22698035

Question

I'm quite simply trying to save an NSMutableArray/NSArray of structs in NSUserDefaults:

typedef struct {
    int key;
} provision;

provision p1;
p1.key = 4;
NSValue *p1Value = [NSValue value:&p1 withObjCType:@encode(provision)];

provision p2;
p2.key = 5;
NSValue *p2Value = [NSValue value:&p2 withObjCType:@encode(provision)];

NSMutableArray *provisions = [[NSMutableArray alloc] init];
[provisions addObject:p1Value];
[provisions addObject:p2Value];

[[NSUserDefaults standardUserDefaults] setObject:provisions forKey:@"Provisions"];

I followed the guide here and store all the structs as NSValue. But that last line causes a runtime error:

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSUserDefaults setObject:forKey:]: attempt to insert non-property list object ( "<04000000>", "<05000000>" ) for key Provisions'

What exactly am I doing wrong?

Était-ce utile?

La solution

From the NSUserDefaults Class Reference:

A default object must be a property list, that is, an instance of (or for collections a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. If you want to store any other type of object, you should typically archive it to create an instance of NSData.

The exception occurs because you try to store an NSValue object. To store the struct as NSData, use

NSData *p1data = [NSData dataWithBytes:&p1 length:sizeof(p1)];

and extract it from NSData with

[p1data getBytes:&p1 length:sizeof(p1)];

Autres conseils

Do you really need to use a struct? If not, using a class instead of a struct would be better. Or you could even create a class to wrap your struct. To me, this would seem clearer (and therefore less prone to mistakes) than what you are try to do. Anyway, you can also do it as Martin R suggests.

NOTE: As MartinR points out in his comment to my answer, you also need NSData to add custom objects to NSUserDefaults.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top