You should always send an autoreleased object (or release it after) to your initialisers - the memory management rules don't change in this instance.
In your example, I'd do this:
-(id) init {return [self initWithName:[[NSString new] autorelease]]]}
This will fix your memory leak and still allow in place constructing.
However, you don't need an extra retain when passing through your initializers - what you're doing with self
is fine. As a rule, +alloc
retains the object once, and -init
methods don't retain further. -init
will be called many times as the [super init]
calls go up the class tree, but the object should only be retained once when it's finally returned to the caller - +alloc
has already done this for you.
However, convenience methods that don't contain the words init, copy or new should return an autoreleased object. As an example:
+(MyObject *)objectWithName:(NSString *)aName {
return [[[MyObject alloc] initWithName:aName] autorelease];
}
FWIW, I normally have -init as my designated initializer, so in case I forget and send -init to an object (or someone else does the same), you don't get a trash object. For instance:
-(id)init {
if (self = [super init]) {
[self setName:[[NSString new] autorelease]];
myReallyImportantiVar = [[NSArray alloc] init];
// etc;
}
return self;
}
-(id)initWithName:(NSString *)aName {
if (self = [self init]) {
[self setName:aName];
}
return self;
}
This may be slightly less efficient (when you're using -initWithName:, setName is called twice), but it's much safer.