好的,有两个指定的初始化器?

时间:2012-05-14 05:17:31

标签: iphone objective-c ios cocoa-touch design-patterns

我在UIViewController的子类中有以下内容;

- (id) initWithFullScreen
{
    self = [super initWithNibName:nil bundle:nil];

    if (self) 
    {
        _fullScreen = YES;
    }

    return self;     
}
- (id) init
{
    self = [super initWithNibName:nil bundle:nil];

    if (self) 
    {
        _fullScreen = NO;
    }

    return self; 
}

- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{
    return [self init];
}

正如您所看到的那样,它们并不像推荐的那样被链接在一起,因为有两个初始化器将超类命名为初始化器。这样可以吗?

3 个答案:

答案 0 :(得分:2)

为什么不这样做呢:

- (id)initWithFullScreen:(BOOL)useFullScreen
{
  self = [super initWithNibName:nil bundle:nil];
  if(self) {
    _fullScreen = useFullScreen;
  }
  return self;
}

- (id)init
{
  return [self initWithFullScreen:NO];
}

- (id)initWithNibNameBlahBlahBlah...
{
  return [self init];
}

答案 1 :(得分:2)

是的,没关系。

指定的初始化程序不是Objective-C语言的一部分,它只是一个约定。通常,如果您通过一个init方法路由所有内容,则不必担心在您可能想要提供的所有其他便捷init方法中复制代码。

当您想要创建子类时,它还可以让您知道应该在超类上调用哪个init方法。 (实际上,您的第三个init方法initWithNibName...违反了此规则。您只需调用init而不是调用超类的指定初始值设定项。)

在您的情况下,使用方法签名initWithFullScreen:(BOOL)fullScreen声明初始化程序并将其指定为指定的初始化程序可能就是这样。在此之内你确保你调用超类的指定初始化程序,你就是。

然后,如果您愿意,可以创建便利初始值设定项:initWithFullScreeninitWithoutFullScreen;他们都会打电话给你指定的初始化程序。例如:

- (id)initWithoutFullScreen
{
    return [self initWithFullScreen:NO];
}

所以,打破常规是可以的。你可能有理由。但是如果坚持下去,通常会更容易保持代码的组织。

修订

要获得额外的功劳,请考虑NSCoding协议,该协议要求类具有initWithCoder:方法。有人可能会说它违反了规则,因为采用NSCoding且其超类也采用NSCoding的类必须准备好有两条初始化路径:一个调用initWithCoder:的{​​{1}}方法和常规指定的初始化器。 / p>

答案 2 :(得分:1)

将其视为methods而不是initializers。所以是的,你可以拥有任意数量的methods
同时尝试在nibNameOrNilnibBundleOrNil中使用initWithFullScreeninit,除非您确实不需要它们。
同样为了简单起见,您可以使用这样的方法

- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil fullScreen:(BOOL)useFullScreen
{
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
      {
         _fullScreen = useFullScreen;
      }
    return self;
}