NSUserDefaults won't save NSDictionary
I'm writing an application which uses NSUserDefaults as the data storage mechanism, and am hitting a problem when trying to save data (that conforms to the Property List protocols):
+ (BOOL)开发者_如何学CstoreAlbum:(Album *)album
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *albums = (NSMutableDictionary *)[prefs objectForKey:@"my_adventure_book_albums"];
NSLog(@"Existing albums: %@",albums);
if (!albums)
albums = [NSMutableDictionary dictionaryWithObject:album forKey:@"album"];
else
[albums setObject:album forKey:@"album"];
NSLog(@"%@",album);
[prefs setObject:albums forKey:@"my_adventure_book_albums"];
return [prefs synchronize];
}
I get this output:
2010-06-29 17:17:09.929 MyAdventureBook[39892:207] Existing albums: (null)
2010-06-29 17:17:09.930 MyAdventureBook[39892:207] test
2010-06-29 17:17:09.931 MyAdventureBook[39892:207] *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '{
album = test;
}' of class 'NSCFDictionary'.
The description method of Album looks like:
- (NSString *)description
{
// Convert to a NSDictionary for serializing
if (!title) title = @"";
if (!date) date = [NSDate dateWithTimeIntervalSinceNow:0];
if (!coverImage) coverImage = @"";
if (!images) images = [[NSArray alloc] initWithObjects:@"",nil];
//NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:title,date,coverImage,images,nil] forKeys:[NSArray arrayWithObjects:@"title",@"date",@"coverImage",@"images",nil]];
//NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:title,nil] forKeys:[NSArray arrayWithObjects:@"title",nil]];
//return [dict description];
return @"test";
}
All of the commented-out lines have the same result, so I just decided to see if the NSString "test" would work, which it (of course) doesn't.
But the object you put inside the dictionary, an Album*
is most likely not a property list object, is it? Every object, all the way down, needs to be a property list object for this to work. A description
method isn't good enough to make this happen.
As a workaround, you can use NSCoding
and an NSKeyedArchiver
to write out your dictionary to an NSData
, which you can store among the preferences.
You can only put basic foundation types into a property list. NSUserDefaults writes preferences out as a property list. See here for property list allowed types. In a nutshell, it is numbers, strings, data, dates, and arrays and dictionaries of those. Dictionaries must have string keys.
NSUserDefaults always returns immutable objects, so you can't just cast them to mutable. Do [prefs objectForKey:@"my_adventure_book_albums"] mutableCopy]
(and remember to release it when finished).
精彩评论