Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Designated initializer should only invoke a designated initializer on 'super'

Tags:

objective-c

This code is a modified version of Ordered Dictionary implemented here. https://github.com/nicklockwood/OrderedDictionary/tree/master/OrderedDictionary

Interface -> OrderedDictionary.h

 @interface OrderedDictionary : NSMutableDictionary
{
}

Implementation -> OrderedDictionary.m

// This is the new method added.
- (instancetype)init
{
    return [self initWithCapacity:0];
}

- (instancetype)initWithCapacity:(NSUInteger)capacity
{
    self = [super init];
    if (self != nil)
    {
       // Allocate here.
    }
    return self;
}

The code works fine but I get following warnings in "- (instancetype)init".

  1. Designated initializer should only invoke a designated initializer on 'super'
  2. Designated initializer missing a 'super' call to a designated initializer of the super class

What am I doing wrong and how do I fix it?

Made following changes to the code to fix the problem

 // This is the new method added.

- (instancetype)init
{
    self = [super init];
    if (self != nil)
    {
       // Allocate here.
    }
    return self;
}

- (instancetype)initWithCapacity:(NSUInteger)capacity
{
    self = [super initWithCapacity:capacity];
    if (self != nil)
    {
       // Allocate here.
    }
    return self;
}
like image 342
Vishvesh Avatar asked Mar 30 '15 14:03

Vishvesh


People also ask

What is a designated initializer?

A designated initializer, or designator, points out a particular element to be initialized. A designator list is a comma-separated list of one or more designators. A designator list followed by an equal sign constitutes a designation.

Why do we need convenience initializer of the same task can be obtained with designated initializer?

A convenience initializer is a secondary initializer that must call a designated initializer of the same class. It is useful when you want to provide default values or other custom setup. A class does not require convenience initializers.

What is the difference between convenience and designated initializer?

A designated initializer fully initializes all properties introduced by that class and calls an appropriate superclass initializer to continue the initialization process up to the superclass chain. Convenience initializers are secondary, supporting initializers for a class.

How many types of Initializers are there in Swift?

Swift defines two kinds of initializers for class types to help ensure all stored properties receive an initial value. These are known as designated initializers and convenience initializers.


2 Answers

try adding - (instancetype)initWithCapacity:(NSUInteger)capacity NS_DESIGNATED_INITIALIZER;

To the @interface block. All initialization paths should flow through the designated initializer - in your case initWithCapacity: is the obvious choice since init calls it. You may still run into problems, the designated initializer must call the super class's designated initializer. If the super class defines designated initializers those must be implement by your class as well...

In general subclassing NSMutableDictionary is considered bad practice because NSMutableDictionary is the public facing piece of a class cluster. This may be part of the cause of the compiler warnings.

like image 123
KirkSpaziani Avatar answered Oct 23 '22 07:10

KirkSpaziani


As you can read in NSMutableDictionary documentation, there are two designated initializer for this class:

  • initWithCapacity: Designated Initializer
  • init Designated Initializer

Here you are calling from initWithCapacity in your class to super.init. That's the reason the compiler warns you.

This code maybe is better:

// This is the new method added.
- (instancetype)init
{
    return [self initWithCapacity:0];
}

- (instancetype)initWithCapacity:(NSUInteger)capacity
{
    self = [super initWithCapacity:capacity];
    if (self != nil)
    {
       // Allocate here.
    }
    return self;
}
like image 1
Diego Freniche Avatar answered Oct 23 '22 05:10

Diego Freniche