web-dev-qa-db-fra.com

Remplacer init dans la sous-classe

Dans Objective-C, est-il nécessaire de remplacer tous les constructeurs hérités d'une sous-classe pour ajouter une logique d'initialisation personnalisée?

Par exemple, les éléments suivants seraient-ils corrects pour une sous-classe UIView avec une logique d'initialisation personnalisée?

@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
38
hpique

Chaque classe Cocoa Touch (et Cocoa) a un initialiseur désigné; pour UIView, comme indiqué dans cette documentation , cette méthode est initWithFrame:. Dans ce cas particulier, vous n'aurez qu'à remplacer initWithFrame; tous les autres appels tomberont en cascade et atteindront finalement cette méthode.

Cela va au-delà de la portée de la question, mais si vous finissez par créer un initialiseur personnalisé avec des paramètres supplémentaires, vous devez vous assurer de l'initialiseur désigné pour la superclasse lors de l'attribution de self, comme ceci:

- (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;
}
41
Sam Ritchie

En cas d'utilisation d'Interface Builder, celui qui est appelé est:

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
       //do sth
    }
    return self;
}
4
letanthang

En général, vous devez suivre la convention d'initialisation désignée. L'initialiseur désigné est l'init, qui couvre l'initialisation de toutes les variables d'instance. L'initialiseur désigné est également la méthode qui est appelée par d'autres méthodes init d'une classe.

Documentation d'Apple sur les initialiseurs désignés.

initWithFrame: est l'initialiseur désigné de la classe NSView. La documentation Cocoa d'Apple mentionne toujours explicitement l'initialiseur désigné d'une classe.

initWithCoder: est discuté ici sur SO .

4
Thomas Zoechling