In the source code I found in a book there's an implementation of -initWithCoder: that basically looks like this: Code: - (id)initWithCoder:(NSCoder *)decoder { if (self = [super init]) { NSData *data = [decoder decodeObjectForKey:kImageKey]; self = [self initWithData:data]; } return (self); } But, this looks potentially problematic. Isn't something like this better and safer? Code: - (id)initWithCoder:(NSCoder *)decoder { NSData *data = [decoder decodeObjectForKey:kImageKey]; self = [self initWithData:data]; return (self); } If super's init creates some internal variables directly, without accessing them through properties, then things allocated in first -init call would leak.
Yes I would not call init twice. However if you're subclassing a class that does conform to NSCoding you'd want to do it like this: Code: - (id)initWithCoder:(NSCoder *)decoder { if (self = [super initWithCoder:decoder]) self.data = [decoder decodeObjectForKey:kImageKey]; return self; } so watch out for what your superclass is.
Thanks, but, in this case the whole point was that the superclass does not conform to NSCoding. That is why, unlike your example, the code above creates complete instace of the class, not just one property. It is from the book by Deitels & co. and adds a category to UIImage to make it conform to NSCoding. Here's the complete listing, containing both original code an my modification. Code: @implementation UIImage (NSCoding) - (id)initWithCoder:(NSCoder *)decoder { // Old version // if (self = [super init]) { // NSData *data = [decoder decodeObjectForKey:kImageKey]; // // self = [self initWithData:data]; // initialize the UIImage with data // } NSData *data = [decoder decodeObjectForKey:kImageKey]; self = [self initWithData:data]; // initialize the UIImage with data return (self); } - (void)encodeWithCoder:(NSCoder *)encoder { NSData *data = UIImagePNGRepresentation (self); // get the PNG representation of the UIImage [encoder encodeObject:data forKey:kImageKey]; } @end
The problem is that if you leave out the call to [super init], you may be skipping some initializing steps that need to take place for the superclass.
But -initWithData: of UIImage surely took care of that. self = [self initWithData:data] probably ends up doing something like if (self = [super init]) in the very first line of that method. It just can't be anything else.