CommaToast
CommaToast

Reputation: 12188

Is calling [self init] OK in Objective C custom init methods as long as init calls [super init]?

Is calling [self init] OK in Objective C custom init methods as long as init calls [super init]?

I.e. lets say we have a class which has 10 different custom init methods (each one returns a differently configured object from the class). Most of these set a unique set of properties of the item.

However all of these custom init methods set _foo = @"bar";.. so can we move _foo = @"bar" into the regular init and be guaranteed it will get called? Or do all of our custom init methods have to call [super init] themselves?

I can't think of a reason why it would be bad if they call [self init] since it, in turn, calls [super init]. If that's somehow inadvisable, could you potentially explain why?

I.e. is it safe to call [self init] in initSalesReceiptWithTicket in the example below:

- (instancetype)init
{
    self = [super init];
    if (self) {
        _foo = @"bar";
    }
    return self;
}

- (instancetype)initSalesReceiptWithTicket:(TicketModel * _Nonnull)ticket {
    self = [self init];
    if (self) {
        NSError *error;

        /* header */
        error = [self populateTotalsFieldsForTicket:ticket];
        if(error) {
            CLS_LOG(@"Error in populating header fields for ticket. \n   Error: %@ \n    Ticket: %@",error,ticket);
        }

        // ... REST OF CODE ...
    }
    return self;
}

- (NSError *)populateTotalsFieldsForTicket:(TicketModel *)ticket {
    NSError *error;

    _subTotal        = [GlobalUtility checkNull:ticket.ticketSubTotal];
    _tax             = [GlobalUtility checkNull:ticket.ticketTaxAmount];
    _taxPercentage   = [GlobalUtility checkNull:ticket.ticketTaxPercentage];
    _total           = [GlobalUtility checkNull:ticket.orderTotal];

    if(_total == 666.666) {
        error = [NSError errorWithDomain:@"hell" code:666 userInfo:@{@"foo":@"bar"}];
    }

    return error;
}

Upvotes: 2

Views: 2153

Answers (1)

Jon Reid
Jon Reid

Reputation: 20980

Yes, that's the way to do it. More precisely, there should be a Designated Initializer that other initializers call. In your example, the plain -init is your Designated Initializer.

See "Multiple Initializers and the Designated Initializer": https://developer.apple.com/library/content/documentation/General/Conceptual/CocoaEncyclopedia/Initialization/Initialization.html#//apple_ref/doc/uid/TP40010810-CH6-SW3

Upvotes: 3

Related Questions