I'm trying to avoid duplicate code in various -(id)init
flavors of a class, i.e. init
, initWithFrame
, initWithCoder
, etc. by defining a private method that is named commonConstruct
.
This method does the heavy lifting common to all init method flavors and gets called by the init
constructor.
The issue i have now is that in derived classes, using the same naming convection for the initializer helper ("commonConstruct") the base class will call the derived class's commonConstruct
, though it is invisible
, i.e. declared in the .m
file, not in the .h
file.
However, the runtime finds the overloaded commonConstruct and executes that instead of its own member function.
Is there any other way than using a different name for the initializer helper in each subclass ?
In other words: Is there a way of making Objective-C
member functions that are "non-virtual", i.e. don't have late (runtime) but compile-time binding?
There's no good compiler-enforced way to do this. Methods are always “virtual” and there is no enforcement of “private” methods.
The common solution is to embed the class name in the method name, thus:
@implementation Thing
- (instancetype)init {
if (self = [super init]) {
[self Thing_commonInit];
}
return self;
}
- (instancetype)initWithArg:(NSObject *)arg {
if (self = [super init]) {
[self Thing_commonInit];
[self doSomethingWithArg:arg];
}
return self;
}
- (void)Thing_commonInit {
...
}
In addition to Rob Mayoff's solution (which I use as well) you could use a static C function:
@implementation Thing
{
id _privateIvar;
}
- (id)init
{
return commonInit([super init], nil);
}
- (id)initWithArgument:(id)argument
{
return commonInit([super init], argument);
}
static Thing *commonInit(Thing *self, id argument)
{
if (self == nil)
return nil;
self->_privateIvar = argument;
return self;
}
@end
Static functions don't emit symbols, so there are no possible conflicts. You can name all of your common initializers commonInit
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With