I’ve been using Objective-C for a while, but I’ve not been following Apple’s guidelines very well. Recently I read Cocoa Design Patterns and the Model Object Implementation Guide, and I’m trying to do some very simple things, but do them very well.
Have I missed any major concepts? Please don’t mention self = [super init]; that’s been covered many times on SO already. Feel free to critique my #pragma marks though!
#import "IRTileset.h"
#import "IRTileTemplate.h"
@interface IRTileset () //No longer lists protocols because of Felixyz
@property (retain) NSMutableArray* tileTemplates; //Added because of TechZen
@end
#pragma mark -
@implementation IRTileset
#pragma mark -
#pragma mark Initialization
- (IRTileset*)init
{
if (![super init])
{
return nil;
}
tileTemplates = [NSMutableArray new];
return self;
}
- (void)dealloc
{
[tileTemplates release];
[uniqueID release]; //Added because of Felixyz (and because OOPS. Gosh.)
[super dealloc]; //Moved from beginning to end because of Abizern
}
#pragma mark -
#pragma mark Copying/Archiving
- (IRTileset*)copyWithZone:(NSZone*)zone
{
IRTileset* copy = [IRTileset new];
[copy setTileTemplates:tileTemplates]; //No longer insertTileTemplates: because of Peter Hosey
[copy setUniqueID:uniqueID];
return copy; //No longer [copy autorelease] because of Jared P
}
- (void)encodeWithCoder:(NSCoder*)encoder
{
[encoder encodeObject:uniqueID forKey:@"uniqueID"];
[encoder encodeObject:tileTemplates forKey:@"tileTemplates"];
}
- (IRTileset*)initWithCoder:(NSCoder*)decoder
{
[self init];
[self setUniqueID:[decoder decodeObjectForKey:@"uniqueID"]];
[self setTileTemplates:[decoder decodeObjectForKey:@"tileTemplates"]]; //No longer insertTileTemplates: because of Peter Hosey
return self;
}
#pragma mark -
#pragma mark Public Accessors
@synthesize uniqueID;
@synthesize tileTemplates;
- (NSUInteger)countOfTileTemplates
{
return [tileTemplates count];
}
- (void)insertTileTemplates:(NSArray*)someTileTemplates atIndexes:(NSIndexSet*)indexes
{
[tileTemplates insertObjects:someTileTemplates atIndexes:indexes];
}
- (void)removeTileTemplatesAtIndexes:(NSIndexSet*)indexes
{
[tileTemplates removeObjectsAtIndexes:indexes];
}
//These are for later.
#pragma mark -
#pragma mark Private Accessors
#pragma mark -
#pragma mark Other
@end
(Edit: I’ve made the changes suggested so far and commented which answers discuss them, in case anyone needs to know why.)
So, why aren’t you doing that?
The same goes for
initWithCoder:: You should be using the object returned by[self init], not assuming that it initialized the initial object.As Abizern said in his comment,
[super dealloc]should come last. Otherwise, you’re accessing an instance variable of a deallocated object.The return type here should be
id, matching the return type declared by the NSCopying protocol.You’re inserting zero or more objects at one index. Create your index set with a range: location = 0, length = the count of the
tileTemplatesarray. Better yet, just assign to the whole property value:Or access the instance variables directly:
(Note that you must do the
copyyourself when bypassing property accessors, and that you arecopying the array on behalf of the copy.)copyWithZone:should not return an autoreleased object. According to the memory management rules, the caller ofcopyorcopyWithZone:owns the copy, which means it is the caller’s job to release it, notcopyWithZone:‘s.You may want to implement the single-object array accessors as well:
This is optional, of course.