指定的初始化程序只应在“超级”上调用指定的初始值设定项。

时间:2015-03-30 14:41:04

标签: objective-c

此代码是此处实现的有序字典的修改版本。 https://github.com/nicklockwood/OrderedDictionary/tree/master/OrderedDictionary

界面 - > OrderedDictionary.h

 @interface OrderedDictionary : NSMutableDictionary
{
}

实施 - > 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;
}

代码工作正常,但我在“ - (instancetype)init”中收到以下警告。

  1. 指定的初始化程序应该只调用指定的初始值设定项 在'超级'
  2. 指定的初始化程序错过了对a的“超级”调用 指定超类的初始化者
  3. 我做错了什么,我该如何解决?

    对代码进行更改以解决问题

     // 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;
    }
    

4 个答案:

答案 0 :(得分:4)

尝试添加      - (instancetype)initWithCapacity:(NSUInteger)容量NS_DESIGNATED_INITIALIZER;

到@interface块。所有初始化路径都应该流经指定的初始化程序 - 在你的情况下,initWithCapacity:是init调用它的明显选择。您可能仍然遇到问题,指定的初始化程序必须调用超类的指定初始化程序。如果超类定义了指定的初始化程序,则必须由您的类实现...

通常,子类化NSMutableDictionary被认为是不好的做法,因为NSMutableDictionary是类集群的公共对象。这可能是编译器警告原因的一部分。

答案 1 :(得分:1)

正如您在NSMutableDictionary documentation中所读到的,这个类有两个指定的初始值设定项:

  • initWithCapacity:指定初始值设定项
  • init指定初始值设定项

在这里,您要从类中的initWithCapacity调用super.init。这就是编译器警告你的原因。

这段代码可能更好:

// 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;
}

答案 2 :(得分:0)

当你让Xcode将你的代码转换为“现代Objective-C语法”时,我敢打赌你们中的一些人正在绊倒这条警告信息。

我见过转换器修改了Objective-C头文件的情况,有两个指定的初始值设定项:

- (instancetype) init NS_DESIGNATED_INITIALIZER;                                    // DO NOT USE
- (instancetype) initWithFileset: (NSArray *) fileset NS_DESIGNATED_INITIALIZER;    // use this to instantiate

如果将此代码修改为单个初始值设定项,您可能会发现警告消息消失:

- (instancetype) init;                                                              // DO NOT USE
- (instancetype) initWithFileset: (NSArray *) fileset NS_DESIGNATED_INITIALIZER;    // use this to instantiate

简而言之,当您看到此警告消息时,请检查标题和源文件。

答案 3 :(得分:-1)

你应该只调用你自己的超级功能。

所以替换

self = [super init]; 

self = [super initWithCapacity:capacity];