views:

333

answers:

2

I have an array that I'm saving to NSUserDefaults, containing an array of my custom class Assignment, which conforms to the NSCoding protocol. The array saves and loads properly, and I can verify that the retrieved first object of the array is of the class Assignment. The problem happens when I try to access ivars of the Assignment object in the array. It crashes and I get the following error:

*** -[CFString respondsToSelector:]: message sent to deallocated instance 0x3948d60

Here is the code I'm using to save to user defaults. Note that I am also retrieving and checking the saved object for debugging purposes.

 -(void)saveToUserDefaults:(NSArray*)myArray
{
    NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];

    if (standardUserDefaults) {
     [standardUserDefaults setObject:[NSKeyedArchiver archivedDataWithRootObject:myArray] forKey:@"Assignments"];
     [standardUserDefaults synchronize];
    }
    NSLog(@"Assignments array saved. (%d assignments in array)",[myArray count]);
    NSData *dataCheck = [[NSData alloc] initWithData:[standardUserDefaults objectForKey:@"Assignments"]];
    NSArray *arrayCheck = [[NSArray alloc] initWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:dataCheck]];
    NSLog(@"Checking saved array (%d assignments in array)",[arrayCheck count]);
    if ([[arrayCheck objectAtIndex:0] isKindOfClass:[Assignment class]]) {
     NSLog(@"It's of the class Assignment.");
    }
    Assignment *testAssignment = [[Assignment alloc] initWithAssignment:[arrayCheck objectAtIndex:0]];
    NSLog(@"Title: %@ Course: %@",[testAssignment title],[testAssignment course]);
}

Everything is fine until I allocate testAssignment, which is where the crash happens. Does anyone have any ideas?

EDIT: Here are my NSCoding methods in the Assignment class:

- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:title forKey:@"title"];
    [coder encodeObject:course forKey:@"course"];
    [coder encodeObject:dueDate forKey:@"dueDate"];
    [coder encodeObject:notes forKey:@"notes"];
}

- (id)initWithCoder:(NSCoder *)coder {
    self = [[Assignment alloc] init];
    if (self != nil)
    {
        title = [coder decodeObjectForKey:@"title"];
        course = [coder decodeObjectForKey:@"course"];
     dueDate = [coder decodeObjectForKey:@"dueDate"];
     notes = [coder decodeObjectForKey:@"notes"];
    }   
    return self;
}
+1  A: 

Answered my own question. In initWithCoder, I needed to retain all of the objects I was decoding:

//Example    
title = [[coder decodeObjectForKey:@"title"] retain];

Everything works beautifully now. :)

Arman
A: 

Thank you for your question and its answer, it helped me a lot

El Chris