Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write an Objective-C convenience constructor

Tags:

objective-c

I'm trying to add a convenience constructor to my custom object. Similar to [NSArray arrayWithArray:]

I know it involves a class method that returns an auto released object. I've been googling around but all I can seem to find is the definition of a convenience constructor but not how to write one.

like image 986
Christian Schlensker Avatar asked Aug 12 '11 20:08

Christian Schlensker


2 Answers

Let's say you have the following:

@class PotatoPeeler : NSObject
- (instancetype)initWithWidget: (Widget *)w;
@end

Then to add a factory method, you'd change it to this:

@class PotatoPeeler : NSObject
+ (instancetype)potatoPeelerWithWidget: (Widget *)w;
- (instancetype)initWithWidget: (Widget *)w;
@end

And your implementation would simply be:

+ (instancetype)potatoPeelerWithWidget: (Widget *)w {
    return [[[self alloc] initWithWidget: w] autorelease];
}

Edit: replaced id with instancetype. They are functionally identical, but the latter provides better hints to the compiler about the method's return type.

like image 165
Jonathan Grynspan Avatar answered Oct 04 '22 18:10

Jonathan Grynspan


Generally my approach is the following: first I create a normal initializer method (instance method), then I create a class method that calls the normal initializer. It seems to me Apple uses the same approach most of the time. An example:

@implementation SomeObject

@synthesize string = _string; // assuming there's an 'string' property in the header

- (id)initWithString:(NSString *)string 
{
   self = [super init];
   if (self)
   {
      self.string = string;
   }
   return self;
}

+ (SomeObject *)someObjectWithString:(NSString *)string
{
   return [[[SomeObject alloc] initWithString:string] autorelease];
}

- (void)dealloc
{
   self.string = nil;

   [super dealloc];
}

@end
like image 40
Wolfgang Schreurs Avatar answered Oct 04 '22 18:10

Wolfgang Schreurs