Re: [Q] Why unsolicited dealloc in NSKeyedUnarchiver?
Re: [Q] Why unsolicited dealloc in NSKeyedUnarchiver?
- Subject: Re: [Q] Why unsolicited dealloc in NSKeyedUnarchiver?
- From: "Peter.Teeson" <email@hidden>
- Date: Tue, 20 Apr 2004 15:03:56 -0400
Thank you for trying to help me. I am quite ready to admit my memory
management is incorrect but as yet I do not understand where.
Please be patient with me as I'm a newbie .. thanks. I tried doing a
retain but to no avail.
Here is an abstract of the interface file. As you can see I have a
MutableArray Data Source that holds PasswordRecords.
// This is the Data Source for the TableView
@interface PasswordsDataSource : NSObject{
NSMutableArray *passwordRecs; // Mutable array of PasswordRecord
objects
}
-(id)initWithCoder:(NSCoder *)coder; // designated initialiser
......
@end
// Each Password record is displayed as one row in the NSTableView
@interface PasswordRecord : NSObject {
NSString *clientID; // Our customers identification
NSCalendarDate *createdTS; // Timestamp of when we created this record
NSString *macAddress; // Ethernet card MAC address
NSString *password; // Generated password
}
-(id)initWithCoder:(NSCoder *)coder; // designated initialiser
......
@end
The only initializer methods for the PasswordDataSource are these two
- (id)init {
[self initWithCoder:nil];
return self;
}
-(id)initWithCoder:(NSCoder *)coder {
self = [super init];
passwordRecs = [[NSMutableArray alloc] init];
[self addPasswordRecord];
if ([coder allowsKeyedCoding]) { // no nil when called from
NSKeyedUnarchiver unarchiveObjectWith
Data:data
passwordRecs = [coder decodeObjectForKey:@"passwordRecs"];
}
return self;
}
and the only initializer methods for thePasswordRecord are these two.
I also show one of the accessor methods to explicate their memory
management.
// init method makes sure that the instance variables are set to
default values
- (id)init {
[self initWithCoder:nil];
return self;
}
-(id)initWithCoder:(NSCoder *)coder {
if (self = [super init]) {
[self setClientID:@"Replace me"];
[self setCreatedTS:[NSCalendarDate calendarDate]]; // Now
[self setMACAddress:@"01-23-45-67-89-AB"];
[self setPassword:@"replace it"];
}
if ([coder allowsKeyedCoding]) {// When called from init coder will be
nil
[self setClientID:[coder decodeObjectForKey:@"clientID"]];
[self setCreatedTS:[coder decodeObjectForKey:@"createdTS"]];
[self setMACAddress:[coder decodeObjectForKey:@"macAddress"]];
[self setPassword:[coder decodeObjectForKey:@"password"]];
}
return self;
}
- (void)setClientID:(NSString *)theClientID {
[theClientID retain];
[clientID release];
clientID = theClientID;
}
......
>
>
> From MyDocument
>
> - (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString
>
> *)aType {
>
> passwordRecords = [NSKeyedUnarchiver unarchiveObjectWithData:data];
>
> return YES;
>
> }
>
>
You should be retaining passwordRecords, since you're getting it from
>
a method that isn't an alloc or copy and you presumably want to keep
>
it around.
>
>
> From PasswordsDataSource designated initializer
>
> -(id)initWithCoder:(NSCoder *)coder {
>
> self = [super init];
>
> passwordRecs = [[NSMutableArray alloc] init];
>
> [self addPasswordRecord];
>
> if ([coder allowsKeyedCoding]) {
>
> passwordRecs = [coder decodeObjectForKey:@"passwordRecs"];
>
> }
>
> return self;
>
> }
>
>
The idiom is to check for a nil result from [super init]. Also,
>
you're leaking an NSMutableArray, since you +alloc and then -init one,
>
assign it to passwordRecs, and then assign an autoreleased object to
>
passwordRecs.
>
>
You should also make sure the memory management is correct in your
>
accessor methods. While it may not be in the above code, it sounds
>
like your memory management is a little out of whack.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.