0

I have a custom object that has as a property, and NSArray of another set of custom NSDictionary objects. When I encode and decode the array, the NSDictionary objects are empty when they should have value. Everything I have read says that NSArray objects conform to NSCoding, but I feel like there must be something more I need to do to properly encode the NSDictionary objects within the NSArray... What am I missing?

@interface Game : NSObject <NSMutableCopying, NSCoding>
@property int rows;
@property int cols;
@property NSMutableArray *troughs;

- (void)encodeWithCoder:(NSCoder *)encoder {

    // encoding properties
    [encoder encodeInteger:rows forKey:@"rows"];
    [encoder encodeInteger:cols forKey:@"cols"];
    [encoder encodeObject:troughs forKey:@"troughs"];
}

- (id)initWithCoder:(NSCoder *)coder {
    self = [super init];
    if (self) {
        rows = (int)[coder decodeIntegerForKey:@"rows"];
        cols = (int)[coder decodeIntegerForKey:@"cols"];
        troughs = [coder decodeObjectForKey:@"troughs"];
    }
    return self;
}

The array of troughs contains objects defined as:

@interface Trough : NSDictionary <NSMutableCopying, NSCoding>
@property int col;
@property int row;
@property BOOL isLocked;
@property NSMutableArray *tokens;

- (void)encodeWithCoder:(NSCoder *)encoder {
    // encoding properties
    [encoder encodeInteger:col forKey:@"col"];
    [encoder encodeInteger:row forKey:@"row"];
    [encoder encodeBool:isLocked forKey:@"isLocked"];
    [encoder encodeObject:tokens forKey:@"tokens"];
}

- (id)initWithCoder:(NSCoder *)coder {
    self = [super init];
    if (self) {
        col = (int)[coder decodeIntegerForKey:@"col"];
        row = (int)[coder decodeIntegerForKey:@"row"];
        isLocked = [coder decodeBoolForKey:@"isLocked"];
        tokens = [coder decodeObjectForKey:@"tokens"];
    }
    return self;
}
1
  • 1
    Why is Trough a subclass of NSDictionary instead of NSObject? Commented May 17, 2016 at 2:50

1 Answer 1

2

Very unusual to subclass NSDictionary. If those NSCopying implementations are to have any chance of working, they will need to call the inherited behavior, too.

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [super encodeWithCoder:aCoder];
    // encode your Trough properties
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        // decode your trough properties
    }
    return self;
}
Sign up to request clarification or add additional context in comments.

1 Comment

That was a great tip! I realized that I didn't need Trough to be of type NSDictionary. Switched it to NSObject and things are working MUCH better. I didn't try calling super. I had tried things like that at various points. But the NSDictionary documentation doesn't say that it conforms to NSCoding, so I assumed it didn't. Anyway, I think I am good to go now. THANKS!!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.