0

有人可以教我从 nib 文件加载视图层次结构的正确方法吗?我正在使用加载的视图作为模板来删除一系列视图,而我当前使用的方法被巧妙地破坏了。我似乎没有在应该复制或保留的时候复制或保留。以下是相关代码:

// pageSet is a list of view tag numbers I'll be using
for (NSNumber *n in pageSet) {

    NSUInteger viewTag = [n integerValue];

    // Ingest the nib. Should there be a copy or retain here?
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"RandomStripe" owner:self options:nil];

    // Pull the view from the nib. Should there be a copy or retain here?
    MyView *view = (MyView *)[topLevelObjects objectAtIndex:0];

    // The view has a label as it's subview
    UILabel *pageNumberLabel = [view.subviews objectAtIndex:0];
    pageNumberLabel.text     = [NSString stringWithFormat:@"%d", viewTag];

    CGFloat xOffset = ((float) viewTag) * self.scrollView.bounds.size.width;

    view.frame = CGRectMake(xOffset, 0, self.scrollView.bounds.size.width, self.scrollView.bounds.size.height);
    view.tag = viewTag;

    // Insert the view as a child of my containerView
    [self.containerView addSubview:view];

} // for (pageSet)

这让我头疼一阵子了?

干杯,道格

4

2 回答 2

2

如果你在 Interface Builder 中使用 IBOutlets 回到你的代码中,事情会容易一些。这样,一旦您尝试访问已设置的 UIView 插座,它就会被加载,并带有所有子级,然后 UIView 的 initWithCoder 将被调用(如果您已将其子类化,则很有用)。

@property (retain, nonatomic) IBOutlet iiView   *iiView;

否则,我这样做:

if (self.numberView == nil) {
    NumberView  *numView = [[NumberView alloc] initWithNibName:@"NumberView" bundle:[NSBundle mainBundle]];
    self.numberView = numView;
    [numView release];
}

(使用 numberView 的 IBOutlet,我只是继续并开始使用 numberView 而不是上面的代码)

在这两种情况下,numberView 的所有子视图(子视图)都将同时加载。如果我需要访问标签或按钮,我也会为它们做一个 IBOutlet,这样我就不必遍历视图层次结构来寻找它们。

IBOutlet UIButton *nextButton,
          *stopButton1,
          *stopButton2,
          *infoButton,
          *bitsonthegoButton;
IBOutlet UILabel *pointsLabel1,
         *pointsLabel2,
         *totalPointsLabel1,
         *totalPointsLabel2;
于 2009-10-06T03:39:10.613 回答
0

我不确定其他答案在这一点上是否完全清楚,但是您在视图上设置的任何 IBOutlets 都将与您今天正在执行的相同 loadNibNamed: 通话连接。因此,在该视图的标题中,您将为 myView 和 pageNumberLabel 声明 IBOutlets,然后将它们附加到 xib 中的文件所有者(并将文件所有者类型设置为您正在调用 loadNibNamed: 的视图)。

那只是为了让你的生活更轻松。要回答您提出的问题,“loadNibNamed:owner:options”的文档告诉我们:

您应该手动保留返回的数组或其中包含的对象,以防止 nib 文件对象过早释放。

所以数组是自动释放的,其中的所有对象也是如此(你会期望调用返回一个自动释放的数组)。由于您想保留视图,因此您将保留该视图 - 这样做意味着主视图的任何子视图也将被保留,因为视图将保留任何设置为子视图的内容。如果您还保留了释放主视图时会导致泄漏的标签,除非您同时释放标签(但这样做似乎没有意义)。

但是请注意,当我说“保留视图”时,您已经在发布的代码中这样做了,只需将其作为子视图添加到您的容器视图中 - 如前所述,视图保留子视图。如果 MyView 从子视图中删除,它将被释放,因此如果您出于任何原因这样做并希望保留它,您会希望保留它。

Nib 加载内存管理起初看起来很复杂,但实际上规则比看起来要简单得多。

于 2009-10-06T05:05:40.943 回答