Normally, you define init or initWith… methods and call them inside convenient constructors like this:
@implementation MyClass1 : NSObject
@synthesize n, s;
-(id)init
{
self = [super init];
if (self) {
self.n = 1;
}
return self;
}
-(id)initWithString:(NSString *)s
{
self = [self init];
if (self) {
self.s = s;
}
return self;
}
+(id)myClass
{
return [[self alloc] init];
}
+(id)myClassWithString:(NSString *)s
{
return [[self alloc] initWithString:s];
}
@end
But I think it is possible to define convenient constructors without defining init or initWith… methods like this:
@implementation MyClass2
@synthesize n, s;
+(id)myClass
{
MyClass2 *obj = [[self alloc] init];
obj.n = 1;
return obj;
}
+(id)myClassWithString:(NSString *)s
{
MyClass2 *obj = [self myClass];
obj.s = s;
return obj;
}
@end
Is it bad practice to define convenient constructors without defining init method?
If it is bad practice, could you tell me the disadvantage or problems?
I’m not sure if it’s actually a bad practice. Generally, when I write convenience constructors they look like this:
The code still takes into account possible memory issues (initialisation failure) like in a ‘normal’ init constructor. Values will only be set if initialisation is successful.
The interface file is defined as such:
Please note the properties are readonly. I prefer creating immutable objects, since they’re easier to deal with in e.g. threaded code. The only way to have the properties set in this situation is by using the convenience constructor.
When I create the convenience constructors, these are generally the only methods I use to instantiate the objects. That is to say, the
-initmethod will not be used most of the time. Also, writing lots of initialisers even if you don’t use them takes lots of developer time. I wouldn’t create methods that I don’t use.When you create code as part of a framework -code that you share with lots of people that you don’t know- in such situations you might want to write both the convenience constructors as well as all the normal constructors, because you can’t be sure how the code will be used in people’s own project. For example creating lots of objects using convenience constructors in tight loops might be bad for performance, since the objects are added to the autorelease pool. I think this is also true in an ARC scenario. In such situations one might have the option to use ‘normal’ constructors to create objects.