为什么为UINavigaionController的子类调用默认构造函数和自定义构造函数?

时间:2012-08-13 12:20:01

标签: objective-c ios cocoa-touch uikit

   @implementation NVController
//Plain Init method
-(id)init
{

    self=[super init];
    if(self)
    {
    }
    return self;
}

//CustomInit Method
-(id)initWithRootViewController:(UIViewController *)rootViewController
{

    self=[super initWithRootViewController:rootViewController];
    if(self)`enter code here`
    {
    }
    return self;
}

@end

NVController *instance=[[NVController alloc] initWithRootViewController:nil];

此处在上面的情况中,由于我只调用initWithRootViwController,因此还会调用另一个构造函数init。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

我猜initWithRootViewController:的实现方式如下:

-(id)initWithRootViewController:(UIViewController *)rootViewController
{
    self=[self init];
    if(self)
    {
        // do something with rootViewController
    }
    return self;
} 

答案 1 :(得分:2)

这是因为您没有正确实现初始化程序。

在Objective C中有一个指定初始化程序的概念,是您的类的单个init函数,所有其他初始化程序必须调用它。指定的初始值设定项直接调用[super init];所有其他初始化程序需要通过调用指定的初始化程序间接调用[super init]

在您的特定情况下,您需要将initinitWithRootViewController:的公共代码(如果有)移动到initWithRootViewController:初始化程序中,并重写普通init如下:

-(id)init {
    return [self initWithRootViewController:nil];
}

**编辑:**(响应指示此解决方案导致无限递归的注释)我认为您获得无限递归的原因必须专门针对UINavigationController的实现细节,这不应该被继承。根据Apple的文档,

  

UINavigationController类实现了一个专门的视图控制器,用于管理分层内容的导航。此类不适用于子类。相反,在希望应用程序的用户界面反映内容的层次结构特性的情况下,可以按原样使用它的实例。

编辑:在iOS 6中取消了对子类的禁止 - 请参阅UINavigationController的文档。