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

문제

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?

도움이 되었습니까?

해결책

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)];

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top