I was reading more about the instancetype
on Stack Overflow and now my question is:
For every convenience constructor that I write, do I need to have the corresponding one using init
?
For example:
RandomItem.h
#import <Foundation/Foundation.h>
@interface RandomItem : NSObject
@property (nonatomic, copy) NSString *aString;
+(instancetype)itemWithString:(NSString *)string;
@end
RandomItem.m
#import "RandomItem.h"
@implementation RandomItem
+(instancetype)itemWithString:(NSString *)string
{
RandomItem *anItem = [[self alloc] init];
anItem.aString = string;
return anItem;
}
@end
And compare this when using an -initWithString:
constructor as well:
RandomItem.h
#import <Foundation/Foundation.h>
@interface RandomItem : NSObject
@property (nonatomic, copy) NSString *aString;
-(id)initWithString:(NSString *)string;
+(instancetype)itemWithString:(NSString *)string;
@end
RandomItem.m:
#import "RandomItem.h"
@implementation RandomItem
-(id)initWithString:(NSString *)string
{
self = [super init];
if (self)
{
self.aString = string;
}
return self;
}
+(instancetype)itemWithString:(NSString *)string
{
return [[self alloc] initWithString:string];
}
@end
I suppose that both cases are fine, but I would like to hear your comments.
Thanks!
-
\$\begingroup\$ I've answered below, but wondering whether this question might be more appropriate for programmers.stackexchange.com, or maybe Stack Overflow? \$\endgroup\$Adam Sharp– Adam Sharp2013年07月16日 11:27:30 +00:00Commented Jul 16, 2013 at 11:27
-
\$\begingroup\$ Having said that, it probably falls within "Best practices and design pattern usage". :) \$\endgroup\$Adam Sharp– Adam Sharp2013年07月16日 11:30:56 +00:00Commented Jul 16, 2013 at 11:30
2 Answers 2
Personally I would prefer the second option because it makes it easier/less weird for subclasses to use and override alloc-init.
As a side node I would point to some reasons to reconsider user properties in your constructors.
It's not necessary to match your initialisers with your class convenience constructor, especially in an ARC environment.
Take a look at the class documentation for UICollectionViewLayoutAttributes
as an example from Apple — it defines three different convenience constructors, but no initialisers other than -init
.
However, if you're not using ARC, there is a difference in memory management semantics: class constructors are expected to return autoreleased objects (and must be explicitly retained to transfer ownership to the caller). Or, more correctly, an object created by any method beginning with alloc
, new
, copy
, or mutableCopy
is owned by the caller (and thus any object that you are sending an init...
message). See Apple's memory management guide.