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 mark
s 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.)
Please don't mention
self = [super init]
…
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.
- (void)dealloc { [super dealloc]; [tileTemplates release]; }
As Abizern said in his comment, [super dealloc]
should come last. Otherwise, you're accessing an instance variable of a deallocated object.
- (IRTileTemplate*)copyWithZone:(NSZone*)zone
The return type here should be id
, matching the return type declared by the NSCopying protocol.
{ IRTileset* copy = [IRTileset new]; [copy insertTileTemplates:tileTemplates atIndexes:[NSIndexSet indexSetWithIndex:0]]; [copy setUniqueID:uniqueID];
You're inserting zero or more objects at one index. Create your index set with a range: location = 0, length = the count of the tileTemplates
array. Better yet, just assign to the whole property value:
copy.tileTemplates = self.tileTemplates;
Or access the instance variables directly:
copy->tileTemplates = [tileTemplates copy];
(Note that you must do the copy
yourself when bypassing property accessors, and that you are copy
ing the array on behalf of the copy.)
return [copy autorelease]; }
copyWithZone:
should not return an autoreleased object. According to the memory management rules, the caller of copy
or copyWithZone:
owns the copy, which means it is the caller's job to release it, not copyWithZone:
's.
@synthesize tileTemplates; [et al]
You may want to implement the single-object array accessors as well:
- (void) insertObjectInTileTemplates:(IRTileTemplate *)template atIndex:(NSUInteger)idx;
- (void) removeObjectFromTileTemplatesAtIndex:(NSUInteger)idx;
This is optional, of course.