UIViewController:[super init]调用[self initWithNibName bundle:]

时间:2012-12-04 14:13:24

标签: objective-c ios uiviewcontroller xib

我的UIViewController子类中有两个init函数:

- (id)init
{
    self = [super init];
    if (self)
    { 
           // Custom stuff
        return self;
    }
    return nil;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName: nibNameOrNil 
                           bundle: nibBundleOrNil];
    if (self) 
    {
        // Custom stuff
    }
    return self;
}

我将init函数放入以避免调用initWithNibName:bundle:方法。我试图尝试取出xib文件。不幸的是,调用这个init [[Myclass alloc] init]调用initWithNibName:bundle:通过调用[super init]。

首先,我应该阅读文档中的哪些内容,以便我可以期望调用父init方法来调用我自己的initWithNibName:bundle:method?

其次,这对Apple来说是一个很好的设计选择。我不明白为什么这是可取的行为? (这可能是因为我没有在这里得到大局,所以请随时告诉我。)

第三,我如何最好地解决它。我只是从我的代码中取出initWithNibName:bundle:从来没有我希望选择使用xib或手动实例化类的选项。

4 个答案:

答案 0 :(得分:6)

通常我必须使用托管对象上下文初始化我的视图控制器。我实现了简单的-(id)initWithContext:方法,我在其中调用了超级initWithNibName:bundle:方法。这样我就可以定义自己的xib名称。

不确定你的问题的第一部分(阅读的东西,但是),但是用于VC的Apple的类模板显示他们有自己的initWithNibName:bundle方法,它使用相同的参数调用super 。因此,根据您的情况,我会说这确实是指定的初始化程序,并且在super上调用简单init方法并不“安全”,因为它将调用initWithNibName:bundle。我相信UIViewController的init看起来像这样:

- (id)init
{
  self = [self initWithNibName:nibNameDerivedFromClass bundle:probablyNilOrMainBundle];

  if (!self) return nil;

  // some extra initialization

  return self;
}

由于超级类没有initWithNibName:bundle,因此必须自行调用方法,使其成为指定的初始化程序。由于你已经覆盖它,ObjC的运行时用你的类替换该方法中的self

答案 1 :(得分:2)

如果要从创建UIViewController的GUI中排除Interface Builder,则必须覆盖loadView并自行创建视图。不要实施initWithNibName:bundle:

- (void)loadView {
    // Init a view. The frame will be automatically set by the view controller.
    UIView *view = [[UIView alloc] initWithFrame:CGRectZero];

    // Add additional views (buttons, sliders etc.) to your view here.

    // Set the view controller's view to the new view.
    self.view = view.
}

答案 2 :(得分:0)

  

首先,我应该阅读文档中的哪个位置以便我这样做   我希望调用父init类来调用我自己的   initWithNibName:bundle:method?

你没有,这是一个设计的东西。 init不是所有类的基本初始化方法

  

其次,这对Apple来说是一个很好的设计选择。我不是   看到为什么这是理想的行为? (可能是我不是   在这里大局,所以请随时提醒我。)

init调用它时,它会发送nil name和bundle,它默认为空的xib文件。总有一个xib文件,无论你是不是。

  

第三,我如何最好地解决它。我只是拿走了   initWithNibName:bundle:我的代码?从来没有我的情况   想要使用xib或手动实例化的选项   该课程。

你没有。如果你只是在调用super,只是转发方法,那么你真的不需要那些代码。

答案 3 :(得分:-3)

您可以自定义视图并在viewDidLoad方法中添加子视图。在此方法中,您可以检查类是使用init还是使用initWithNibName创建的:bundle:通过检查属性nibName。使用init时,nibName将为nil。

- (void)viewDidLoad
{
    [super viewDidLoad];
    if (!self.nibName) {
        // View was not loaded from nib - setup view
    }
}