【问题标题】:Is the Syntax self = [self init] Acceptable in an Initialization Method at All?语法 self = [self init] 在初始化方法中是否可以接受?
【发布时间】:2026-01-10 15:55:02
【问题描述】:

在某些情况下,self = [self init]init 方法中被调用,而不是在我查看的代码中的 [super init] .如果导致使用 [self init],您认为这种语法是可以接受的还是表明逻辑在某些方面排列错误(错误的模式)?

例如(可能是另一个例子),

- (instancetype)init {
  self = [super init];
  //my code block
  return self;
}

- (instancetype)initWithDelegate:(id<MyDelegate>)delegate {
  self = [self init]; //self = [super init] is not called since "my code block" needs to be implemented
  if (self) {
    self.delegate = delegate;
  }
  return self;
}

self = [self init] 可以这样吗?如果有,你有什么例子吗?

【问题讨论】:

    标签: objective-c initialization self


    【解决方案1】:

    上面的代码是倒退的。指定的初始化程序是initWithDelegate:(因为它是初始化所有属性的初始化程序)。所以init 应该调用initWithDelegate:

    - (instancetype)init {
      self = [self initWithDelegate:nil];
      return self;
    }
    
    - (instancetype)initWithDelegate:(id<MyDelegate>)delegate {
      self = [super init];
      if (self) {
        //my code block
        self.delegate = delegate;
      }
      return self;
    }
    

    请参阅iOS Designated Initializers : Using NS_DESIGNATED_INITIALIZER,了解如何在标题中正确注释您指定的初始化程序。

    当然每个人都应该听James Dempsey sing about how this mistake impacted him

    对于self = [self init] 是否正确的基本问题,在大多数应用程序级代码(即库之外)中会令人惊讶。指定初始化程序通常是采用最多参数的初始化程序,因此当有多个初始化程序时,init 是最不可能的候选者。另一方面,self = [self init...] 非常常见且正确。

    但是,在具有您无法控制的现有子类的代码中(例如,如果您发布了一个库),它可能仅以 init 开始生命,并且后来添加了其他初始化程序。在这种情况下,保持init 的指定通常是明智的(这样现有的子类就不必重写),在这种情况下,当然self = [self init] 可能是正确的。

    【讨论】:

      最近更新 更多