【问题标题】:Objective-C: How to prevent a non-default initializer from being called? [duplicate]Objective-C:如何防止调用非默认初始化程序? [复制]
【发布时间】:2014-01-13 13:27:11
【问题描述】:

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

例如

/* everyone must call this */
- (id)initWithInfo:(NSDictionary *)info {
  self = [super init];
  if (self) {
      _info = info;
  }

  return self;
}

/* Don't want anyone to be able to create this using init */

【问题讨论】:

标签: objective-c initializer


【解决方案1】:

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

因此你不能删除超类的方法。

用户/开发人员也可以使用任何其他方式创建新对象,例如newinitWith...

【讨论】:

    【解决方案2】:

    虽然您不能删除超类初始化器,但您可以通过像这样覆盖它们来“阻止”它们:

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

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

    【讨论】:

    • 为什么要打电话给[super init]
    • 我猜你可能不需要。
    • 如果失败,断言不会触发。这没有道理。它“失败得相当快”。
    • 只是为了你,我会将断言移到条件之外。这里酱汁的重要部分是-doesNotRecognizeSelector:
    • 为全人类,甚至只是为了自己。不要担心我,因为我不会使用代码。
    【解决方案3】:

    你可以试试这个:

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

    【讨论】:

    • 如何将数据传递给 someDictionary???上课前?
    • 问题的所有想法都是使用自定义字典初始化对象,并且您将其设置为nil
    • 这种方法在你必须做一些自定义初始化的时候很好,但是为了初始化信息字典,必须调用initWithInfo方法。调用init方法没有发送任何内容。
    猜你喜欢
    • 1970-01-01
    • 2015-08-19
    • 2015-01-23
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 2021-07-20
    • 1970-01-01
    • 2017-11-21
    相关资源
    最近更新 更多