覆盖子类中的init

hpi*_*que 38 inheritance initialization objective-c init uiview

在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
Run Code Online (Sandbox Code Playgroud)

Sam*_*hie 42

每个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;
}
Run Code Online (Sandbox Code Playgroud)

  • 重要的是要记住,如果一个对象从NIB实例化,`initWithCoder:`被调用,而**NOT**`initWithFrame:`. (31认同)
  • 因此,在@Pascal评论中,Sam接受的答案是错误的.由于您不能依赖构造函数的约定,因此假设您必须覆盖所有构造函数可能会花费更少的时间,以确保每次都运行init. (4认同)
  • @Pascal这是一个很好的观点,可能应该编辑成答案,来自关于`initWithFrame`的答案中引用的文档:_"如果你使用Interface Builder来设计你的界面,那么当你的视图对象随后被调用时,这个方法就不会被调用从nib文件加载."_ (3认同)
  • @GregoryJohnson不一定是_all_他们; `initWithCoder:`很特别,它是`NSCoding`类的一部分.你可以覆盖指定的初始化程序,在这种情况下`initWithFrame:`,**PLUS**`initWithCoder:`. (2认同)

小智 5

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

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
       //do sth
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)