Objective c 目标C:如何防止调用非默认初始值设定项?

Objective c 目标C:如何防止调用非默认初始值设定项?,objective-c,initializer,Objective C,Initializer,我创建了一个不同的init方法,希望它是指定的初始值设定项,而不是标准的-init。如何防止客户端代码使用-init实例化类 e、 g init来自NSObject的层次结构。每个类都有init 因此,您不能删除超类的方法 用户/开发人员还可以使用任何其他方式创建新对象,如new,initWith…,您可以尝试以下方法: - (id)init { return [self initWithInfo:@{}]; } - (id)initWithInfo:(NSDictionary *)in

我创建了一个不同的init方法,希望它是指定的初始值设定项,而不是标准的
-init
。如何防止客户端代码使用
-init
实例化类

e、 g


init
来自
NSObject
的层次结构。每个类都有
init

因此,您不能删除超类的方法

用户/开发人员还可以使用任何其他方式创建新对象,如
new
initWith…
,您可以尝试以下方法:

- (id)init 
{
  return [self initWithInfo:@{}];
}

- (id)initWithInfo:(NSDictionary *)info 
{
  self = [super init];
  if (self) 
  {
      _info = [NSDictionary dictionaryWithDictionary:info];
  }
  return self;
}

虽然不能删除超类初始值设定项,但可以通过如下方式覆盖它们来“阻止”它们:

- (id)init
{
    NSAssert(NO, @"Use the designated initializer: -initWithInfo:");
    [self doesNotRecognizeSelector: _cmd];
    if (self = [super init])
    {
        self = nil;
    }
    return self;
}

这至少会“快速失败”(在运行时)。如果可以在编译时使其失败,那就太好了,但我不相信在这一点上有任何方法可以实现这一点

旁注:您的方法缺少
返回self是“指定的初始值设定项”,而不是“默认初始值设定项”。可以将
init
映射到另一个
init…
或使其抛出错误。没有办法“隐藏”它。让
init
单独存在,并在文档中提到对象应该如何初始化?可能重复,或者如何将数据传递到某个字典???在分配类之前?问题的全部想法是使用自定义字典初始化对象,并将其设置为
nil
。当您必须进行一些自定义初始化时,这种方法很好,但为了初始化信息字典,必须调用
initWithInfo
方法。调用
init
方法无法发送任何内容。为什么要调用
[super init]
呢?我想您可能不需要这样做。如果失败,断言将不会触发。这毫无意义。它是“相当快地失败”。对于您,我将把断言移到条件之外。这里酱汁的重要部分是
-不认识选择器:
为全人类,甚至是你自己做。不要担心我,因为我不会使用代码。
- (id)init
{
    NSAssert(NO, @"Use the designated initializer: -initWithInfo:");
    [self doesNotRecognizeSelector: _cmd];
    if (self = [super init])
    {
        self = nil;
    }
    return self;
}