NSDictionary with NSNumber to NSString mapping is

2019-01-27 00:31发布

问题:

Following code:

[[NSUserDefaults standardUserDefaults] setObject:photoIdToPath forKey:@"photo_id_to_path"];

gives me the following error:

Attempt to set a non-property-list object {
417675729 = "/Users/k06a/Library/Application Support/iPhone Simulator/7.1/Applications/21163736-DF6F-4E79-8196-6A966C81ED1B/Documents/417675729";
} as an NSUserDefaults value for key photo_id_to_path

Here is photoIdToPath dictionary content analysis from Xcode debug console:

(lldb) po photoIdToPath
{
    417675729 = "/Users/k06a/Library/Application Support/iPhone Simulator/7.1/Applications/21163736-DF6F-4E79-8196-6A966C81ED1B/Documents/417675729";
}

(lldb) po [[[photoIdToPath allKeys] lastObject] class]
__NSCFNumber

(lldb) po [[[photoIdToPath allValues] lastObject] class]
NSPathStore2

So NSPathStore2 is subclass of NSString, why this dictionary is not property list?

UPDATE:

Here https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nsuserdefaults_Class/Reference/Reference.html#//apple_ref/occ/instm/NSUserDefaults/setObject:forKey: I found text:

The value parameter can be only property list objects: NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects. See “What is a Property List?” in Property List Programming Guide.

回答1:

The only way you can save a dictionary to NSUserDefaults (or write the dictionary to a file as a plist), all keys MUST be NSString objects and all values must be valid plist objects.

In other words, you can't have keys that are NSNumber objects. Convert them to NSString if you need to write the dictionary to NSUserDefaults.

For details on this, see the Property List Programming Guide. Specifically the section titled What is a Property List?. There is a table showing the XML tags used. Under that table you will see this excerpt:

And although NSDictionary and CFDictionary objects allow their keys to be objects of any type, if the keys are not string objects, the collections are not property-list objects.