谁能用自己的话解释init和initWithFrame调用的先后顺序原因

这是一个自定义view:

@implementation MyView

- (instancetype)init {
    if (self = [super init]) {
        NSLog(@"调用了init");
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        NSLog(@"调用了initWithFrame");
    }
    return self;
}


@end

现在我调用它的init方法:

MyView *myView = [[MyView alloc] init];

控制台打印信息是:
2017-10-09 11:14:35.224 block[2391:262544] 调用了initWithFrame
2017-10-09 11:14:35.225 block[2391:262544] 调用了init

问:
为什么先打印的是initWithFrame而不是init?

阅读 6.6k
2 个回答
MyView *myView = [[MyView alloc] init];

代码调用过程如下:

  1. 动态查找到 MyView 的 init 方法
  2. 调用 super init 方法
  3. super init 方法内部执行的是 [super initWithFrame:CGRectZero]
  4. 然后 super 会发现 MyView 实现了 initWithFrame 方法
  5. 转而执行 [MyView initWithFrame:CGRectZero]
  6. 最后再执行 init 其余部分

关键点:OC 里面的 super 实际上是让某个类自己去调用父类的方法, 而不是父类去调用某方法。方法动态调用过程中的顺序是按照继承关系从下到上。

  • (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;

NS_DESIGNATED_INITIALIZER 你可以找下关于这个宏定义的资料。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题