0

I have a custom non-ARC init, and I wonder if I should call [super init] before releasing self.

Solution A, not calling [super init] before [self release]:

- (instancetype)initWithInteger:(NSInteger)anInteger
{
    if (anInteger == 0)
    {
        [self release];
        return nil;
    }
    self = [super init];
    if (!self)
        return nil;

    // Initialization code
    self.i = anInteger;

    return self;
}

Solution B, calling [super init] before [self release]:

- (instancetype)initWithInteger:(NSInteger)anInteger
{
    self = [super init];
    if (!self)
        return nil;
    if (anInteger == 0)
    {
        [self release];
        return nil;
    }

    // Initialization code
    self.i = anInteger;

    return self;
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
  • Non-ARC code doesn't require to [self release] just call at starting point of an method self = [super init]; – bhavya kothari Feb 04 '14 at 10:28
  • 2
    @bhavyakothari non-Arc requires you to [self release]: http://stackoverflow.com/questions/2467685/should-i-always-release-self-for-failed-init-methods?rq=1 – Cœur Feb 04 '14 at 11:05

1 Answers1

5

I would go with the second pattern. The reason for this is that super's dealloc might possibly rely on something in super's init having been done to work properly.

Here is a (very) contrived example, this is the init and dealloc method in a class that you are subclassing.

@implementation ASuperClass
{
    char* foo;
}

-(id) init 
{
    self = [super init];
    if (self != nil)
    {
        foo = strdup("blah blah blah");
    }
    return self;
}

-(void) dealloc
{
    if (foo[1] == 'l')
    {
        NSLog(@"Second character was l");
    }
    free(foo);
}

In the above, if this is the class you inherited from, your first pattern will throw an EXC_BAD_ACCESS on a null pointer dereference.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • Good for pointing this out. So `[super init]` is mandatory even when you know you will return nil. – Cœur Feb 04 '14 at 11:04
  • @Cœur If you *know* that nothing in the hierarchy does anything dangerous, you don't need to call `[super init]` but that would be breaking encapsulation, so yes, it is mandatory. – JeremyP Feb 04 '14 at 13:35