Gwendyl
Gwendyl

Reputation: 21

How do I encode/decode a custom object that has an array of custom objects?

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;
}

Upvotes: 0

Views: 733

Answers (1)

danh
danh

Reputation: 62676

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;
}

Upvotes: 2

Related Questions