为什么UIView同时调用init和initWithFrame?

时间:2013-10-17 09:41:18

标签: ios objective-c uiview

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

TestViewController.m:

@implementation TestViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    View1 *view1 = [[View1 alloc] init];
    [self.view addSubview:view1];
}

@end

View1.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

为什么在init之前调用initWithFrame?

3 个答案:

答案 0 :(得分:7)

这不是问题。如果是 UIView ,则[super init]来电将自动更改为[super initWithFrame:CGRectZero]。因此,您必须牢记这一点来维护此代码。

答案 1 :(得分:6)

原因是你在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_(object-oriented_programming)

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

答案 2 :(得分:1)

下面是两种方法的小描述,它将清楚地定义init在initWithFrame之后调用的原因: -

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.