Переопределение init в подклассе
В Objective-C необходимо ли переопределить все наследуемые конструкторы подкласса для добавления пользовательской логики инициализации?
Например, допустимо ли следующее для подкласса UIView
с пользовательской логикой инициализации?
@implementation CustomUIView
- (id)init {
self = [super init];
if (self) {
[self initHelper];
}
return self;
}
- (id)initWithFrame:(CGRect)theFrame {
self = [super initWithFrame:theFrame];
if (self) {
[self initHelper];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
[self initHelper];
}
return self;
}
- (void) initHelper {
// Custom initialization
}
@end
Ответы
Ответ 1
Каждый класс Cocoa Touch (и Cocoa) имеет назначенный инициализатор; для UIView
, как указано в этой документации, этот метод initWithFrame:
. В этом конкретном случае вам нужно только переопределить initWithFrame
; все остальные вызовы будут каскадом вниз и ударить этот метод, в конце концов.
Это выходит за рамки вопроса, но если вы создадите пользовательский инициализатор с дополнительными параметрами, вы должны убедиться в назначении инициализатора для суперкласса при назначении self
, например:
- (id)initWithFrame:(CGRect)theFrame puzzle:(Puzzle *)thePuzzle title:(NSString *)theTitle {
self = [super initWithFrame:theFrame];
if (self) {
[self setPuzzle:thePuzzle];
[self setTitle:theTitle];
[self initHelper];
}
return self;
}
Ответ 2
В общем, вы должны следовать условному соглашению инициализатора. Назначенный инициализатор представляет собой init, который охватывает инициализацию всех переменных экземпляра. Назначенный инициализатор также является методом, который вызывается другими методами init класса.
Apple documentation о назначенных инициализаторах.
initWithFrame:
- назначенный инициализатор класса NSView. Документация Apple Cocoa всегда явно упоминает назначенный инициализатор класса.
initWithCoder:
обсуждается здесь на SO.
Ответ 3
В случае использования Interface Builder, он вызывается:
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
//do sth
}
return self;
}