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