Является ли синтаксис self = [self init] приемлемым в методе инициализации вообще? - PullRequest
0 голосов
/ 29 августа 2018

В некоторых случаях 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] в порядке? Если да, есть ли у вас пример?

1 Ответ

0 голосов
/ 29 августа 2018

Приведенный выше код является обратным. Назначенный инициализатор - 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: Использование NS_DESIGNATED_INITIALIZER , чтобы узнать, как правильно аннотировать назначенный инициализатор в заголовке.

И, конечно, каждый должен слушать Джеймс Демпси поет о том, как эта ошибка повлияла на него .

К основному вопросу о том, является ли self = [self init] когда-либо правильным, это было бы удивительно в большинстве кодов уровня приложения (т.е. вне библиотек). Назначенные инициализаторы обычно являются инициализаторами, которые принимают большинство параметров, поэтому init является наименее вероятным кандидатом при наличии нескольких инициализаторов. С другой стороны, self = [self init...] очень распространено и правильно.

Однако в коде, в котором есть существующие подклассы, которые вы не контролируете (например, если вы отправляете библиотеку), вполне возможно, что она начала жизнь только с init, а другие инициализаторы были добавлены позже. В этом случае часто целесообразно оставить обозначение init (чтобы не пришлось переписывать существующие подклассы), и в этом случае, конечно, self = [self init] может быть правильным.

...