【问题标题】:Designated initializer should only invoke a designated initializer on 'super' When using protocols?指定初始化程序应该只在“超级”上调用指定初始化程序 使用协议时?
【发布时间】:2017-09-22 21:04:51
【问题描述】:

我有以下结构。 我得到了符合protocol Aclass Bprotocol A 定义了一个指定的初始化器,即-(instancetype)initWithInt:(int)count

但是,当我在 class B 中实现标准 -(instancetype)init 并使其使用也在 B 类中实现的指定初始化程序时,我收到警告“指定初始化程序只能在'super'",而我的指定初始化程序(IMO 是 initWithInt)从不调用 super 上的任何指定初始化程序。

@protocol A
{
(instancetype) init;
(instancetype) initWithInt:(NSUInteger)count;
}

@interface B : NSObject <A>

@implementation B
- (instancetype) init {
    return [self initWithInt:0];
}
- (instancetype) initWithInt:(NSUInteger)count {
    self = [super init];
    return self;
}

知道为什么编译器在这种特定情况下会忽略此警告吗?

【问题讨论】:

  • 有什么问题?
  • @matt 刚刚更新了问题部分。
  • 你打算如何使用这个协议?

标签: objective-c xcode objective-c-runtime


【解决方案1】:

来自Working with Protocols

类接口声明与该类关联的方法和属性。相比之下,协议用于声明独立于任何特定类的方法和属性。

每个类都有自己的(继承的)指定初始化程序。您不能在协议中声明指定的初始化程序。如果你想在协议中声明一个初始化器,可以这样实现:

- (instancetype)initWithInt:(NSUInteger)count {
    self = [self initWithMyDesignatedInitializer];
    if (self) {
        // do something with count
    }
    return self;
}

或喜欢:

- (instancetype)initWithInt:(NSUInteger)count {
    return [self initWithMyDesignatedInitializer:count];
}

并且不要在你的协议中声明init,它是由NSObject声明的。

编辑:

在协议中声明初始化器是没有意义的。当你分配和初始化对象时,你知道对象的类,应该调用这个类的指定初始化器。

编辑 2:

指定的初始值设定项特定于一个类并在该类中声明。您可以初始化类的实例,但不能初始化协议的实例。协议可以在不知道该对象的类的情况下与对象对话。关于初始化器的文档:Multiple Initializers and the Designated Initializer.

【讨论】:

  • 您不能在协议中的方法中实现方法,不确定我是否理解您在此处所说的内容。此外,理性地说,在协议中定义指定的初始化程序有什么问题,你反对它的论点没有提供足够的推理。
  • 我想你不明白什么是协议。阅读Working with Protocols
  • 我同意协议独立于类。但是,不允许协议声明指定初始化程序(例如 initWithInt: )的原因是什么,所以只有实现此初始化程序的类才能成功符合协议?这是仍然没有得到答复的缺失部分。
  • 指定初始化器调用其超类的指定初始化器。其他初始化器调用 self 的初始化器。如果我的班级有一个指定的初始化程序initWithString:,我将如何实现initWithInt:?它缺少我的字符串参数。以及如何分配匿名对象并调用initWithInt:
  • 因为苹果是这么说的。我的回答没有用,我会删除它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-11
  • 2016-05-10
  • 1970-01-01
相关资源
最近更新 更多