0

我继承了一个代码库,发现编译器抱怨这段代码:

- (id)initWithFrame:(CGRect)frame {
// is this really missing??
// self = [super initWithFrame:frame];
    self = [[[NSBundle mainBundle] loadNibNamed:@"DigitsKeyboardView" owner:self options:nil] firstObject];
    return self;
}

XCode 抱怨未调用超类中的指定初始化程序。如果我取消注释对 super 的调用,错误就会明显消失。但是由于该应用程序并没有为相当多的 iOS 版本缺少该行而烦恼,我不确定这是否是一个学术要求,或者在这种情况下甚至可能是错误的。

使用 a 调用该loadNibNamed方法selfself然后将其覆盖。这会导致无法立即看到的麻烦吗?

在这种情况下,正确的实施是什么?

4

1 回答 1

2

initWithFrame - 使用指定的框架矩形初始化并返回一个新分配的视图对象。视图的框架矩形,以磅为单位。框架的原点是相对于您计划在其中添加它的超级视图。此方法使用框架矩形来相应地设置中心和边界属性。

参数是 frame - 视图的框架矩形,以点为单位。框架的原点是相对于您计划在其中添加它的超级视图。此方法使用框架矩形来相应地设置中心和边界属性。

所以你应该像这样在下面打电话

- (id)initWithFrame:(CGRect)frame 
{
  self = [super initWithFrame:frame];
  if (self) 
  {
    // Initialization code
    NSArray *arrNibView = [[NSBundle mainBundle] loadNibNamed:@"DigitsKeyboardView" owner:self options:nil];
    UIView  *nibView = (UIView*)[arrNibView objectAtIndex:0]; //Give here your first object
    [self addSubview:nibView];
  }
  return self;
}

如果您有多个自定义视图,并且如果您想将自定义视图用于单独的控制器,则可以使用上述方法。

但是如果你有自定义视图并且如果你想在多个视图控制器中多次使用(重用),你需要同时实现 bot initWithFrame 和 awakeFromNib 方法

- (id)initWithFrame:(CGRect)frame 
{
  self = [super initWithFrame:frame];
  if (self) 
  {
    // Initialization code
    [[NSBundle mainBundle] loadNibNamed:@"DigitsKeyboardView" owner:self options:nil];
    [self addSubview:self.view];
  }
  return self;
}
- (void) awakeFromNib
{
   [super awakeFromNib];
   [self addSubview:self.view];
}

initWithFrame - 建议您实现此方法。除了或代替此方法,您还可以实现自定义初始化方法。

awakeFromNib - awakeFromNib 在视图及其子视图被分配和初始化后被调用。保证视图将设置其所有出口实例变量。

awakeFromNib 详解

在实例化过程中,存档中的每个对象都被取消存档,然后使用适合其类型的方法进行初始化。Cocoa 视图(以及可以使用关联的 Interface Builder 调色板自定义的自定义视图)使用它们的 initWithCoder: 方法进行初始化。自定义视图使用它们的 initWithFrame: 方法进行初始化。已在 nib 中实例化的自定义类使用它们的 init 方法进行初始化。

一旦所有对象都被实例化并从存档中初始化,nib 加载代码会尝试重新建立每个对象的出口和相应的目标对象之间的连接。如果您的自定义对象有出口,一个 NSNib 对象会尝试重新建立您在 Interface Builder 中创建的任何连接。它首先尝试使用对象自己的方法建立连接。对于每个需要连接的出口,NSNib 对象会在您的对象中查找形式为 setOutletName: 的方法。如果该方法存在,则 NSNib 对象将调用它,并将目标对象作为参数传递。如果您没有使用该确切名称定义 setter 方法,NSNib 对象在对象中搜索具有相应出口名称的实例变量(IBOutlet id 类型),并尝试直接设置其值。如果找不到具有正确名称的实例变量,则不会发生该连接的初始化。最后,在所有对象完全初始化后,每个对象都会收到一条 awakeFromNib 消息。

苹果文档

界面视图

initWithFrame

从笔尖醒来

其他来源

加载 Nib 文件

使用 xib 初始化视图

awakeFromNib 调用

viewDidLoad 和 awakeFromNib 计时

于 2016-07-11T11:36:41.163 回答