Objective C: I'm trying to save an NSDictionar

2019-08-01 06:50发布

问题:

So I have this custom object i made called 'Box', it's throwing the error for that one. Inside of my NSDictionary is...

box = [[Box alloc] initWithHeight:20 height:40];    
wrap.dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:numberInt, kInt, numberShort, kShort, numberLong, kLong, numberFloat, kFloat, numberDouble, kDouble, numberBool, kBool, nsString, kString, nsDate, kDate, box, @"keybox", nil];

Notice the box object that I created up top and added in the NSDictionary at the very end. Before when the box wasn't in there, everything worked fine, but when I added the custom object 'Box', it couldn't save anymore.

- (void) saveDataToDisk:(NSMutableDictionary *)dictionaryForDisk 
{
    NSMutableData *data = [NSMutableData data];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
    //Encode 
    [archiver setOutputFormat:NSPropertyListBinaryFormat_v1_0];
    [archiver encodeObject:dictionaryForDisk forKey:@"Dictionary_Key"];

    [archiver finishEncoding];
    [data writeToFile:[self pathForDataFile] atomically:YES];
}

- (NSString *) pathForDataFile {
    NSArray*    documentDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString* path = nil;
    if (documentDir) 
    {
        path = [documentDir objectAtIndex:0];    
    }

    return [NSString stringWithFormat:@"%@/%@", path, @"data.bin"];
}

This was the error

-[Box encodeWithCoder:]: unrecognized selector sent to instance 0x4e30d60
2011-11-11 11:56:43.430 nike[1186:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Box encodeWithCoder:]: unrecognized selector sent to instance 0x4e30d60'
*** Call stack at first throw:

Any help would be greatly appreciated!!!!

回答1:

The exception tells you that it's trying to send -encodeWithCoder: to your Box instance. If you look up the documentation, you can see that this belongs to the NSCoding protocol. NSCoding is used by NSKeyedArchiver to encode objects. NSDictionary's implementation of NSCoding requires that all keys and objects inside it also conform to NSCoding. In your case, all the previous values stored in your dictionary conform to NSCoding, but your Box instance doesn't.

You need to implement -initWithCoder: and -encodeWithCoder: on your Box class and then declare that your class conforms to NSCoding by modifying the declaration to look like

@interface Box : Superclass <NSCoding>


回答2:

Your custom Box class must adhere to the NSCoding Protocol. The protocol documentation is here. Ray Wenderlich has a good tutorial here.