UIView的init与initWithFrame:的调用关系

前言

  凑巧得知了以下现象:

  • 调用UIView子类的init方法会先去调用initWithFrame:
  • 调用UIView子类的initWithFrame:不会调用init方法

  一开始会很自然的认为initWithFrame:多一个参数的方法内部会调用init这个初始化方法,会对上面的现象感到奇怪。但是在用Xcode查看了initinitWithFrame:方法的说明后就了然了。

流程

  先从frame这个UIView的属性入手,当用

1
UIView *v = [[UIView alloc] init];

  用lldb调试打印出frame

  从得到的结果可知:就算只调用init方法,UIView对象的frame也是有值的?

  1. 类似Java类中的基本数据结构,都有默认值
  2. 直接设置frame属性,当前情况下,至少我没有写,虽然最终肯定是要进行设置的
  3. 调用了initWithFrame:方法,传递的参数为CGRectZero

  因为没有UIViewinit方法的具体代码,所以只能算是*揣测*,根据实际的情况,再加上既然已经有了initWithFrame:方法设置frame,应该没必要搞那么麻烦,就第3种情况吧。

调用UIView子类的init方法会先去调用initWithFrame:,这个算是可以成立的

  若init调用initWithFrame:(?),initWithFrame:自然就不会再调用init方法了。

实现

尝试去编写符合上面假设的代码

查看NSObject中的init方法的说明

至少可以得知两点

init是让子类实现初始化一个新对象的方法
NSObject类的init没有初始化操作,只是简单的返回了一个self指针

继承关系为:CustomView -> UIView -> UIResponder -> NSObject

NSObject

1
2
3
4
5
6
7
- (instancetype)init {
self = [super init];
if (self) {
// Initialize self
}
return self;
}

UIView

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (instancetype)init {
self = [super init];
if (self) {
...
[self initWithFrame:CGRectZero];
...
}
return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
self = [super init];
if (self) {
...
self.frame = frame;
...
}
}

CustomUIView

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (instancetype)init {
self = [super init];
if (self) {
...
}
return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
...
}
}
  1. CustomView对象调用init方法
  2. 调用UIViewinit方法
  3. 调用NSObjectinit方法,返回self指针
  4. selfCustomView对象,所以执行CustomView对象的initWithFrame:方法

  1. CustomView对象调用initWithFrame:对象
  2. 调用UIViewinit方法
  3. 调用NSObjectinit方法,返回self指针
  4. 根据传递参数设置frame属性值

参考

理解Block(上) 自动化Git提交
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×