1

我在 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];
}

如您所见,它们并没有像推荐的那样全部链接在一起,因为有两个初始化器调用指定初始化器的超类。这样做可以吗?

4

3 回答 3

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];
}
于 2012-05-14T05:26:27.033 回答
2

好的,可以。

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

它还让您知道当您想要创建子类时应该在超类上调用哪个 init 方法。(实际上,您的第三个 init 方法initWithNibName...违反了此规则。您没有调用超类的指定初始化程序,而是调用init.)

在您的情况下,使用方法签名声明一个初始化程序并将initWithFullScreen:(BOOL)fullScreen其指定为指定的初始化程序可能是要走的路。并且在其中你确保你调用了超类的指定初始化器,你就是。

initWithFullScreen然后,您可以创建便利初始化程序:initWithoutFullScreen如果您愿意;他们都只会调用您指定的初始化程序。例如:

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

所以,打破惯例是可以的。你可能有你的理由。但是,如果您坚持下去,通常更容易使您的代码井井有条。

修正案

额外的功劳,考虑 NSCoding 协议,它要求类有一个initWithCoder:方法。有人可能会说它违反了规则,因为采用 NSCoding 并且其超类也采用 NSCoding 的类必须准备有两条初始化路径:initWithCoder:调用的方法[super initWithCoder:coder]和常规指定的初始化程序。

于 2012-05-14T05:43:41.183 回答
1

将它们视为methods而不是initializers。所以是的,你可以拥有尽可能多methods的。
也尝试使用nibNameOrNiland nibBundleOrNilin initWithFullScreeninit除非你真的不需要它们。
同样为简单起见,您可以使用这样的方法

- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil fullScreen:(BOOL)useFullScreen
{
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
      {
         _fullScreen = useFullScreen;
      }
    return self;
}
于 2012-05-14T05:35:11.050 回答