42

在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
4

3 回答 3

46

每个 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;
}
于 2010-12-05T16:35:14.187 回答
5

在使用 Interface Builder 的情况下,调用的是:

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
       //do sth
    }
    return self;
}
于 2016-11-09T10:00:24.707 回答
4

通常,您应该遵循指定的初始化程序约定。指定的初始化程序是 init,它涵盖了所有实例变量的初始化。指定的初始化器也是一个类的其他init方法调用的方法。

Apple关于指定初始化程序的文档。

initWithFrame:是 NSView 类的指定初始化器。Apple 的 Cocoa 文档总是明确提到类的指定初始化程序。

initWithCoder:在这里讨论SO

于 2010-12-05T16:50:50.967 回答