8

我注意到,当我在子类init和子类中都覆盖时,这两种方法都会被调用。即使在我的代码中只有一个被明确调用:initWithFrame:UIView

测试视图控制器.m:

@implementation TestViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    View1 *view1 = [[View1 alloc] init];
    [self.view addSubview:view1];
}

@end

视图1.m:

@implementation View1

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

- (id)init
{
    self = [super init];
    if (self)
    {
        NSLog(@"init");
    }
    return self;
}

@end

控制台如下所示:

2013-10-17 12:33:46.209 test1[8422:60b] initWithFrame

2013-10-17 12:33:46.211 test1[8422:60b] 初始化

为什么在 init 之前调用 initWithFrame?

4

3 回答 3

8

这不是问题。在UIView的情况下,[super init]调用将自动更改为[super initWithFrame:CGRectZero] . 因此,您必须牢记这一点来维护此代码。

于 2013-10-17T09:55:42.477 回答
7

原因是在View1 initWithFrame:你调用里面[super initWithFrame:]UIView initWithFrame: 打电话[self init]

当您在类中调用方法时,会调用子类上的方法。因此,当您在 UIView 上调用实例方法(例如 init)时,它会尝试在 View1 上调用 init 方法(如果已实现)。

根据以下答案进行编辑:https ://stackoverflow.com/a/19423494/956811

让 view1 成为 View1 的一个实例。
调用层次结构是:

   - [view1(View1) init] 

      - [view1(UIView) init] (called by [super init] inside View1)

        - [view1(View1) initWithFrame:CGRectZero] (called inside [view(UIView) init] )

           - [view1(UIView) initWithFrame:CGRectZero] (called by [super initWithFrame] inside View1) 
              - ...

           - NSLog(@"initWithFrame"); (prints "test1[8422:60b] initWithFrame")

      - NSLog(@"init"); (called inside [view1(View1) init] ; prints "test1[8422:60b] init")

检查 OOP 中的继承。

http://en.wikipedia.org/wiki/Inheritance_(面向对象编程)

http://www.techotopia.com/index.php/Objective-C_Inheritance

于 2013-10-17T09:55:26.663 回答
1

下面是这两种方法的简短描述,它将清楚地定义为什么在 initWithFrame 之后调用 init:-

initWithFrame 方法是做什么的?

Initializes and returns a newly allocated NSView object with a specified 
frame rectangle. This method returns the initialize and allocated object. Once it 
returned the below init method will called automatically.

用什么init方法做的?

 Implemented by subclasses to initialize a new object (the receiver) immediately after 
 memory for it has been allocated.So this init method will called only when memory has 
 been allocated to the object by initwithFrame. 
于 2013-10-17T09:59:01.057 回答