I’m learning Objective-C. In my first non-trivial project I’ve run into a question about how to best handle resources passed to the initializer, compared to the default initializer. My class has a retained resource, engine, which can be set manually after creation, or during initialization explicitly, or during initialization by default:
- (id)init {
if ((self = [super init])) {
id e = [[XorShiftEngine alloc] init];
[self setEngine: e];
[e release];
}
return self;
}
- (id)initWithEngine:(NSObject <RandEngine> *)e {
if ((self = [super init]))
[self setEngine: e];
return self;
}
- (id)setEngine:(NSObject <RandEngine> *)newEngine {
[newEngine retain];
[engine release];
engine = newEngine;
// Some other stuff which needs to happen on changing the engine.
return engine;
}
The default initializer, in particular, seems very ugly to me, interleaving code relevant to the self, then the member, then self again, then the member again, and naming the object solely to be able to release it later. It also violates the designated initializer idiom.
Is there a more idiomatic way to do this, without using autorelease pools?
You’ve done basically the right thing. The only thing I would change is directly assigning the variable and retaining it rather than calling the setter in the init method.
Apple recommends not calling property setters/getters in the init and dealloc methods (I’m assuming you’ve declared a retain property and are just overriding the setter).
If you have engine customization code that needs to happen the first time the engine is set in the initializer as well as whenever it is changed, then you should refactor this out into a separate method.